@secretstache/wordpress-gutenberg 0.4.14 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@secretstache/wordpress-gutenberg",
3
- "version": "0.4.14",
3
+ "version": "0.5.0",
4
4
  "description": "",
5
5
  "author": "Secret Stache",
6
6
  "license": "GPL-2.0-or-later",
@@ -27,7 +27,6 @@ const Control = ({ label, max, min, value, onChange, disabled, tooltip, ...other
27
27
  max={max}
28
28
  marks={generateMarks(min, max)}
29
29
  resetFallbackValue={-1}
30
- help="Use -1 for default settings."
31
30
  renderTooltipContent={(value) => {
32
31
  if (value === -1) return 'Default';
33
32
 
@@ -20,6 +20,6 @@ export const useAllowedBlocks = (blockName, excludedBlocks) => {
20
20
  && (!blockHasAncestor || isAncestor);
21
21
  })
22
22
  ?.map((block) => block.name),
23
- [allBlocks, excludedBlocks, blockName],
23
+ [ allBlocks, excludedBlocks, blockName ],
24
24
  );
25
25
  };
@@ -1,3 +1,4 @@
1
+ import { filters } from '@wordpress/hooks';
1
2
  import apiFetch from '@wordpress/api-fetch';
2
3
  import slugify from 'slugify';
3
4
  import classNames from 'classnames';
@@ -144,3 +145,23 @@ export const getSpacingClasses = (
144
145
  [`${mobilePrefix}pb-${spacing?.mobile?.padding?.bottom}`]: spacing?.mobile?.padding?.bottom !== -1,
145
146
  });
146
147
  };
148
+
149
+ /**
150
+ * @param namespace
151
+ * @returns {*[]}
152
+ */
153
+ const getFiltersByNamespace = (namespace) => {
154
+ const list = [];
155
+
156
+ Object.entries(filters).forEach(([filterName, filterData]) => {
157
+ const handlers = filterData.handlers || [];
158
+
159
+ handlers.forEach((handler) => {
160
+ if (handler.namespace.startsWith(namespace)) {
161
+ list.push({ filterName, namespace: handler.namespace });
162
+ }
163
+ });
164
+ });
165
+
166
+ return list;
167
+ };
@@ -1,5 +1,5 @@
1
1
  export * from './rootBlock/index.js';
2
- export * from './waitForContainer/index.js';
2
+ export * from './rootContainer/index.js';
3
3
 
4
4
  export * from './attributes.js';
5
5
  export * from './constants.js';
@@ -1,25 +1,17 @@
1
1
  import { createBlock } from '@wordpress/blocks';
2
2
  import { dispatch } from '@wordpress/data';
3
3
 
4
- import { waitForContainer } from '../waitForContainer/index.js';
4
+ import { getRootContainer } from '../rootContainer/index.js';
5
5
 
6
- const ROOT_CONTAINER_SELECTOR = '.is-root-container';
7
- const ROOT_BLOCK_APPENDER_SELECTOR = '.is-root-container .root-block-appender';
6
+ const ROOT_BLOCK_APPENDER_SELECTOR = '.root-block-appender';
8
7
 
9
8
  /**
10
9
  * Initializes the custom button for the root appender.
10
+ * @param {Element} rootContainer - The root container of the editor.
11
11
  * @param {string} blockName - The name of the block to be created when the appender is clicked.
12
12
  * @param {string} tooltipText - The tooltip text displayed on the appender.
13
13
  */
14
- const initialize = (blockName, tooltipText) => {
15
- const rootContainer = document.querySelector(ROOT_CONTAINER_SELECTOR);
16
-
17
- if (!rootContainer) {
18
- console.error('Root container not found');
19
-
20
- return;
21
- }
22
-
14
+ const initialize = (rootContainer, blockName, tooltipText) => {
23
15
  const button = document.createElement('button');
24
16
 
25
17
  button.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" focusable="false"><path d="M11 12.5V17.5H12.5V12.5H17.5V11H12.5V6H11V11H6V12.5H11Z"></path></svg>';
@@ -32,6 +24,8 @@ const initialize = (blockName, tooltipText) => {
32
24
  });
33
25
 
34
26
  rootContainer.prepend(button);
27
+
28
+ return !!rootContainer.querySelector(ROOT_BLOCK_APPENDER_SELECTOR);
35
29
  };
36
30
 
37
31
  /**
@@ -42,13 +36,27 @@ const initialize = (blockName, tooltipText) => {
42
36
  * @param {string} [tooltipText='Add Row'] - The tooltip text displayed on the appender.
43
37
  */
44
38
  export const setRootBlockAppender = (blockName, tooltipText = 'Add Row') => {
45
- waitForContainer(() => initialize(blockName, tooltipText), ROOT_CONTAINER_SELECTOR);
39
+ const rootContainer = getRootContainer();
40
+
41
+ if (rootContainer) {
42
+ initialize(rootContainer, blockName, tooltipText);
43
+ } else {
44
+ console.error('Root container is not found.')
45
+ }
46
46
  };
47
47
 
48
48
  export const unsetRootBlockAppender = () => {
49
- const appender = document.querySelector(ROOT_BLOCK_APPENDER_SELECTOR);
50
-
51
- if (appender) {
52
- appender.remove();
49
+ const rootContainer = getRootContainer();
50
+
51
+ if (rootContainer) {
52
+ const appender = rootContainer.querySelector(ROOT_BLOCK_APPENDER_SELECTOR);
53
+
54
+ if (appender) {
55
+ appender.remove();
56
+ } else {
57
+ console.error('Root block appender is not found.');
58
+ }
59
+ } else {
60
+ console.error('Root container is not found.')
53
61
  }
54
- }
62
+ };
@@ -1,4 +1,6 @@
1
- export * from './setRootBlock.js';
2
- export * from './setRootBlockAppender.js';
1
+ export * from './setRootBlockForPostTypes.js'
2
+ export * from './setRootBlockFilter.js'
3
+ export * from './unsetRootBlockFilter.js';
4
+ export * from './rootBlockVisibilityFilter.js';
5
+ export * from './appender.js';
3
6
  export * from './hideRootBlockForInlineInserter.js';
4
- export * from './hideRootBlockForOtherBlocks.js';
@@ -0,0 +1,35 @@
1
+ import { addFilter, removeFilter } from '@wordpress/hooks';
2
+ import { getBlockTypes } from '@wordpress/blocks';
3
+
4
+ export const rootBlockVisibilityFilter = {
5
+ add({ rootBlockName }) {
6
+ addFilter(
7
+ 'blocks.registerBlockType',
8
+ 'ssm/root-block-visibility',
9
+ (blockSettings, blockName) => {
10
+ const isRootBlock = blockName === rootBlockName;
11
+ const hasOwnAllowedBlocks = !!blockSettings?.allowedBlocks;
12
+ const hasParent = !!blockSettings?.parent;
13
+
14
+ if (isRootBlock || hasParent || hasOwnAllowedBlocks) {
15
+ return blockSettings;
16
+ }
17
+
18
+ // get all blockTypes
19
+ blockSettings.allowedBlocks = getBlockTypes()
20
+ ?.filter((allowedBlock) => {
21
+ const isRootBlock = allowedBlock.name === rootBlockName;
22
+ const hasParent = !!allowedBlock?.parent;
23
+
24
+ return !isRootBlock && !hasParent;
25
+ })
26
+ ?.map(allowedBlock => allowedBlock.name);
27
+
28
+ return blockSettings;
29
+ },
30
+ );
31
+ },
32
+ remove() {
33
+ removeFilter('blocks.registerBlockType', 'ssm/root-block-visibility');
34
+ },
35
+ };
@@ -0,0 +1,29 @@
1
+ import { addFilter, removeFilter } from '@wordpress/hooks';
2
+
3
+ /**
4
+ * Adds a filter to set the specified block as the root block by modifying block settings during registration.
5
+ * Blocks other than the root block will have their 'ancestor' property set to the root block name,
6
+ * making them only insertable within the root block.
7
+ */
8
+ export const setRootBlockFilter = {
9
+ add(rootBlockName) {
10
+ addFilter(
11
+ 'blocks.registerBlockType',
12
+ 'ssm/set-root-block',
13
+ (settings, name) => {
14
+ const isRootBlock = name === rootBlockName;
15
+ const isBaseBlock = name === 'core/block';
16
+ const hasAncestor = !!settings?.ancestor;
17
+
18
+ if (!isRootBlock && !isBaseBlock && !hasAncestor) {
19
+ settings.ancestor = [rootBlockName];
20
+ }
21
+
22
+ return settings;
23
+ },
24
+ );
25
+ },
26
+ remove() {
27
+ removeFilter('blocks.registerBlockType', 'ssm/set-root-block');
28
+ },
29
+ };
@@ -0,0 +1,73 @@
1
+ import { dispatch, select, subscribe } from '@wordpress/data';
2
+ import { setRootBlockFilter } from './setRootBlockFilter.js';
3
+ import { unsetRootBlockFilter } from './unsetRootBlockFilter.js';
4
+ import { rootBlockVisibilityFilter } from './rootBlockVisibilityFilter.js';
5
+ import { waitForRootContainer } from '../rootContainer/index.js';
6
+ import { setRootBlockAppender, unsetRootBlockAppender } from './appender.js';
7
+
8
+ /**
9
+ * Configures a root block for specific post types
10
+ *
11
+ * @param {string} rootBlockName - The name of the root block to set.
12
+ * @param {Array<string>} [postTypes=['page', 'post']] - The post types for which the root block should be enabled.
13
+ * @param {Function} [callback] - Optional callback to execute when the root block state changes.
14
+ * @param {Array<Object>} [filters=[rootBlockVisibilityFilter]] - Filters to apply or remove when enabling/disabling the root block.
15
+ * @param {boolean} [initAppender=true] - Whether to initialize the root block appender.
16
+ * @param {string} [appenderTooltipText='Add Row'] - Tooltip text for the root block appender.
17
+ */
18
+ export const setRootBlockForPostTypes = (
19
+ rootBlockName,
20
+ postTypes = ['page', 'post'],
21
+ callback,
22
+ filters = [ rootBlockVisibilityFilter ],
23
+ initAppender = true,
24
+ appenderTooltipText = 'Add Row',
25
+ ) => {
26
+ let isRootBlockEnabled = false;
27
+
28
+ waitForRootContainer().then(() => {
29
+ console.log('Root Container found.');
30
+
31
+ subscribe(() => {
32
+ const currentPostType = select('core/editor').getCurrentPostType();
33
+
34
+ if (postTypes.includes(currentPostType) && !isRootBlockEnabled) {
35
+ isRootBlockEnabled = true;
36
+
37
+ setRootBlockFilter.add(rootBlockName);
38
+ unsetRootBlockFilter.remove();
39
+
40
+ if (filters?.length > 0) {
41
+ filters.forEach((filter) => filter.add({ rootBlockName, isRootBlockEnabled, currentPostType }));
42
+ dispatch('core/blocks').reapplyBlockTypeFilters();
43
+ }
44
+
45
+ if (callback) {
46
+ callback({ isRootBlockEnabled, currentPostType });
47
+ }
48
+
49
+ if (initAppender) {
50
+ setRootBlockAppender(rootBlockName, appenderTooltipText);
51
+ }
52
+ } else if (!postTypes.includes(currentPostType) && isRootBlockEnabled) {
53
+ isRootBlockEnabled = false;
54
+
55
+ setRootBlockFilter.remove()
56
+ unsetRootBlockFilter.add(rootBlockName);
57
+
58
+ if (filters?.length > 0) {
59
+ filters.forEach((filter) => filter.remove({ rootBlockName, isRootBlockEnabled, currentPostType }));
60
+ dispatch('core/blocks').reapplyBlockTypeFilters();
61
+ }
62
+
63
+ if (callback) {
64
+ callback({ isRootBlockEnabled, currentPostType });
65
+ }
66
+
67
+ if (initAppender) {
68
+ unsetRootBlockAppender();
69
+ }
70
+ }
71
+ }, 'core/block-editor');
72
+ })
73
+ };
@@ -0,0 +1,26 @@
1
+ import { addFilter, removeFilter } from '@wordpress/hooks';
2
+
3
+ /**
4
+ * Adds a filter to unset the root block restrictions by removing the 'ancestor' property from block settings
5
+ * if it includes the specified root block name.
6
+ */
7
+ export const unsetRootBlockFilter = {
8
+ add(rootBlockName) {
9
+ addFilter(
10
+ 'blocks.registerBlockType',
11
+ 'ssm/unset-root-block',
12
+ (settings) => {
13
+ const hasRootAncestor = settings.ancestor && settings.ancestor.includes(rootBlockName);
14
+
15
+ if (hasRootAncestor) {
16
+ settings.ancestor = null;
17
+ }
18
+
19
+ return settings;
20
+ },
21
+ );
22
+ },
23
+ remove() {
24
+ removeFilter('blocks.registerBlockType', 'ssm/unset-root-block');
25
+ },
26
+ };
@@ -0,0 +1,72 @@
1
+ ## Overview
2
+
3
+ The `waitForRootContainer` function is a utility that periodically checks for the presence of the Gutenberg editor's root container, identified by the class `.is-root-container`. Once the container is found, it resolves a promise, allowing for additional initialization logic.
4
+
5
+ ## Function Signature
6
+
7
+ ```javascript
8
+ /**
9
+ * Periodically checks for the presence of the Gutenberg editor's root container and resolves when found.
10
+ *
11
+ * @param {number} [maxAttempts=10] - The maximum number of attempts to check for the root container.
12
+ * @param {number} [interval=500] - The interval time (in milliseconds) between attempts.
13
+ * @returns {Promise<Element>} - Resolves with the root container element if found, or rejects if not found after max attempts.
14
+ */
15
+ export const waitForRootContainer = (maxAttempts = 10, interval = 500);
16
+ ```
17
+
18
+ ### Parameters
19
+ - **maxAttempts** (`number`, optional): The maximum number of attempts to check for the root container. Default is `10`.
20
+ - **interval** (`number`, optional): The interval time (in milliseconds) between each attempt. Default is `500`.
21
+
22
+ ### Returns
23
+ - **Promise<Element>**: Resolves with the root container element when found. Rejects with an error if the container is not found after the maximum attempts.
24
+
25
+ ---
26
+
27
+ ## Usage Example
28
+ To use the `waitForRootContainer` function, import it into your script and handle the promise:
29
+
30
+ ```javascript
31
+ import { waitForRootContainer } from '@secretstache/wordpress-gutenberg';
32
+
33
+ waitForRootContainer(10, 500)
34
+ .then((rootContainer) => {
35
+ console.log('Gutenberg root container found:', rootContainer);
36
+ // Your initialization logic here
37
+ })
38
+ .catch((error) => {
39
+ console.error('Failed to find Gutenberg root container:', error);
40
+ });
41
+ ```
42
+
43
+ ### Example Output
44
+ In this example:
45
+ - The function checks for the Gutenberg root container (identified by `.is-root-container`) up to 10 times, waiting 500ms between each check.
46
+ - If the container is found, it resolves with the container element.
47
+ - If the container is not found after 10 attempts, it rejects with an error.
48
+
49
+ ---
50
+
51
+ ## getRootContainer
52
+
53
+ The `getRootContainer` function retrieves the Gutenberg editor's root container element from the DOM.
54
+
55
+ ### Usage Example
56
+
57
+ ```javascript
58
+ import { getRootContainer } from '@secretstache/wordpress-gutenberg';
59
+
60
+ const rootContainer = getRootContainer();
61
+ if (rootContainer) {
62
+ console.log('Gutenberg root container found:', rootContainer);
63
+ } else {
64
+ console.log('Gutenberg root container not found');
65
+ }
66
+ ```
67
+
68
+ ---
69
+
70
+ ### Notes
71
+ - The `getRootContainer` function searches both the main DOM and an iframe (if applicable) for the Gutenberg root container with the class `.is-root-container`.
72
+ - `waitForRootContainer` is built on top of `getRootContainer` and provides retry logic for situations where the root container is not immediately available.
@@ -0,0 +1,42 @@
1
+ const ROOT_CONTAINER_SELECTOR = '.is-root-container';
2
+
3
+ /**
4
+ * Retrieves the Gutenberg editor's root container element from the DOM or an iframe.
5
+ *
6
+ * @returns {Element|null} - Returns the root container element if found, or null if not found.
7
+ */
8
+ export const getRootContainer = () => {
9
+ const rootContainer = document.querySelector(ROOT_CONTAINER_SELECTOR);
10
+
11
+ if (rootContainer) {
12
+ return rootContainer;
13
+ }
14
+
15
+ const iframe = document.querySelector('.block-editor iframe');
16
+ const iframeDocument = iframe?.contentDocument || iframe?.contentWindow?.document;
17
+
18
+ return iframeDocument?.querySelector(ROOT_CONTAINER_SELECTOR) || null;
19
+ };
20
+
21
+ export const waitForRootContainer = (maxAttempts = 10, interval = 500) => {
22
+ return new Promise((resolve, reject) => {
23
+ let attempts = 0;
24
+
25
+ const checkRootContainer = () => {
26
+ const rootContainer = getRootContainer();
27
+
28
+ if (rootContainer) {
29
+ return resolve(rootContainer);
30
+ } else {
31
+ if (attempts <= maxAttempts) {
32
+ attempts++;
33
+ setTimeout(checkRootContainer, interval);
34
+ } else {
35
+ reject(new Error('Root container not found after max attempts.'));
36
+ }
37
+ }
38
+ };
39
+
40
+ checkRootContainer();
41
+ });
42
+ };
@@ -1,156 +0,0 @@
1
- ## setRootBlock
2
-
3
- The `setRootBlock` function configures a root block in the Gutenberg editor for specific post types. It ensures that only the specified root block can be inserted at the root level for those post types. The function dynamically applies or removes the root block restriction based on the current post type. Optionally, it initializes a custom root block appender with customizable tooltip text and allows specifying callbacks for when the post type matches or does not match.
4
-
5
- ### Function Signature
6
-
7
- ```javascript
8
- /**
9
- * Sets the root block in the Gutenberg editor for specific post types and optionally customizes the tooltip text for the root appender.
10
- * The function dynamically applies or removes the root block restriction based on the current post type.
11
- *
12
- * @param {string} rootBlockName - The name of the block to be set as the root block.
13
- * @param {string[]} [postTypes=['page', 'ssm_design_system']] - An array of post types where the root block should be set.
14
- * @param {boolean} [initAppender=true] - Flag to indicate whether to initialize the root appender.
15
- * @param {string} [appenderTooltipText='Add Row'] - The tooltip text to be displayed on the root appender.
16
- * @param {Function} [matchPostTypeCallback=null] - A callback function to execute when the current post type matches the specified post types.
17
- * @param {Function} [notMatchPostTypeCallback=null] - A callback function to execute when the current post type does not match the specified post types.
18
- */
19
- export const setRootBlock = (
20
- rootBlockName,
21
- postTypes = ['page', 'ssm_design_system'],
22
- initAppender = true,
23
- appenderTooltipText = 'Add Row',
24
- matchPostTypeCallback = null,
25
- notMatchPostTypeCallback = null,
26
- );
27
- ```
28
-
29
- #### Parameters
30
-
31
- - **rootBlockName** (`string`): The name of the block to be set as the root block. This parameter is mandatory.
32
- - **postTypes** (`string[]`, optional): An array of post types where the root block should be set. Default is `['page', 'ssm_design_system']`.
33
- - **initAppender** (`boolean`, optional): Flag to indicate whether to initialize the root appender. Default is `true`.
34
- - **appenderTooltipText** (`string`, optional): The tooltip text to be displayed on the root appender. Default is `'Add Row'`.
35
- - **matchPostTypeCallback** (`Function`, optional): A callback function to execute when the current post type matches the specified post types. Default is `null`.
36
- - **notMatchPostTypeCallback** (`Function`, optional): A callback function to execute when the current post type does not match the specified post types. Default is `null`.
37
-
38
- ### Usage Example
39
-
40
- To use the `setRootBlock` function, import it into your script and pass the necessary parameters:
41
-
42
- ```javascript
43
- import domReady from '@wordpress/dom-ready';
44
- import { setRootBlock } from '@secretstache/wordpress-gutenberg';
45
-
46
- domReady(() => {
47
- setRootBlock(
48
- 'ssm/section-wrapper',
49
- ['page', 'post'],
50
- true,
51
- 'Add Section',
52
- () => {
53
- console.log('Root block set for matching post type.');
54
- },
55
- () => {
56
- console.log('Root block unset for non-matching post type.');
57
- }
58
- );
59
- });
60
- ```
61
-
62
- In this example, the function will:
63
-
64
- - Set `'ssm/section-wrapper'` as the root block for 'page' and 'post' post types.
65
- - Initialize the root appender with the tooltip text 'Add Section'.
66
- - Execute the `matchPostTypeCallback` when the current post type matches 'page' or 'post'.
67
- - Execute the `notMatchPostTypeCallback` when the current post type does not match.
68
-
69
- The function monitors the current post type and dynamically applies or removes the root block restriction as needed.
70
-
71
- ---
72
-
73
- ## setRootBlockAppender
74
-
75
- The `setRootBlockAppender` function creates a new top-level block appender in the Gutenberg editor. It allows you to specify the block name to be created when the appender is clicked and customize the tooltip text displayed on the appender.
76
-
77
- ### Function Signature
78
-
79
- ```javascript
80
- /**
81
- * Creates a new top-level block appender. It allows specifying the block name to be
82
- * created when the appender is clicked and customizing the tooltip text displayed on the appender.
83
- *
84
- * @param {string} blockName - The name of the block to be created when the appender is clicked.
85
- * @param {string} [tooltipText='Add Row'] - The tooltip text displayed on the appender.
86
- */
87
- export const setRootBlockAppender = (blockName, tooltipText = 'Add Row');
88
- ```
89
-
90
- #### Parameters
91
-
92
- - **blockName** (`string`): The name of the block to be created when the appender is clicked. This parameter is mandatory.
93
- - **tooltipText** (`string`, optional): The tooltip text displayed on the appender. Default is `'Add Row'`.
94
-
95
- ### Usage Example
96
-
97
- In your custom theme or plugin, you can import and initialize the function with the desired block name and tooltip text:
98
-
99
- ```javascript
100
- import domReady from '@wordpress/dom-ready';
101
- import { setRootBlockAppender } from '@secretstache/wordpress-gutenberg';
102
-
103
- domReady(() => {
104
- setRootBlockAppender('ssm/section-wrapper', 'Add Section');
105
- });
106
- ```
107
-
108
- In this example, clicking the appender will insert the `'ssm/section-wrapper'` block, and the tooltip on the appender will display 'Add Section'.
109
-
110
- ---
111
-
112
- ## unsetRootBlockAppender
113
-
114
- The `unsetRootBlockAppender` function removes the custom root block appender from the Gutenberg editor.
115
-
116
- ### Function Signature
117
-
118
- ```javascript
119
- /**
120
- * Removes the custom root block appender from the Gutenberg editor.
121
- */
122
- export const unsetRootBlockAppender = () => {};
123
- ```
124
-
125
- ### Usage Example
126
-
127
- To remove the custom root block appender, simply call the function:
128
-
129
- ```javascript
130
- import { unsetRootBlockAppender } from '@secretstache/wordpress-gutenberg';
131
-
132
- unsetRootBlockAppender();
133
- ```
134
-
135
- ---
136
-
137
- ### Notes
138
-
139
- - The `setRootBlock` function internally manages the application and removal of the root block restrictions based on the current post type. It also handles the initialization and removal of the root block appender if `initAppender` is set to `true`.
140
- - The `matchPostTypeCallback` and `notMatchPostTypeCallback` parameters allow you to execute custom logic when the post type matches or does not match the specified `postTypes` array. This can be useful for additional configurations or side effects needed in your application.
141
- - The functions `setRootBlockAppender` and `unsetRootBlockAppender` can be used independently if you need to manually control the appender outside of the `setRootBlock` function.
142
-
143
- ### Additional Example
144
-
145
- If you want to set a root block without initializing the appender and without specifying callbacks:
146
-
147
- ```javascript
148
- import domReady from '@wordpress/dom-ready';
149
- import { setRootBlock } from '@secretstache/wordpress-gutenberg';
150
-
151
- domReady(() => {
152
- setRootBlock('ssm/section-wrapper', ['page'], false);
153
- });
154
- ```
155
-
156
- In this case, the root block `'ssm/section-wrapper'` will be set for the 'page' post type, but the root appender will not be initialized.
@@ -1,33 +0,0 @@
1
- import { addFilter } from '@wordpress/hooks';
2
- import { getBlockTypes } from '@wordpress/blocks';
3
- import { dispatch } from '@wordpress/data';
4
-
5
- export const hideRootBlockForOtherBlocks = (rootBlockName) => {
6
- addFilter(
7
- 'blocks.registerBlockType',
8
- 'ssm/hide-root-block-for-other-blocks',
9
- (blockSettings, blockName) => {
10
- const isRootBlock = blockName === rootBlockName;
11
- const hasOwnAllowedBlocks = !!blockSettings?.allowedBlocks;
12
- const hasParent = !!blockSettings?.parent;
13
-
14
- if (isRootBlock || hasParent || hasOwnAllowedBlocks) {
15
- return blockSettings;
16
- }
17
-
18
- // get all blockTypes
19
- blockSettings.allowedBlocks = getBlockTypes()
20
- ?.filter((allowedBlock) => {
21
- const isRootBlock = allowedBlock.name === rootBlockName;
22
- const hasParent = !!allowedBlock?.parent;
23
-
24
- return !isRootBlock && !hasParent;
25
- })
26
- ?.map(allowedBlock => allowedBlock.name);
27
-
28
- return blockSettings;
29
- },
30
- );
31
-
32
- dispatch('core/blocks').reapplyBlockTypeFilters();
33
- };