@secretstache/wordpress-gutenberg 0.6.16 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/editor-canvas.css +1 -1
- package/build/index.js +3216 -3193
- package/build/index.js.map +1 -1
- package/package.json +8 -2
- package/src/components/EmptyBlockPlaceholder.jsx +67 -0
- package/src/components/IconPicker.jsx +4 -5
- package/src/components/MediaControl.jsx +14 -15
- package/src/components/MediaWithFocalPointControl.jsx +10 -11
- package/src/components/PatternAppender.jsx +24 -0
- package/src/components/PatternsModal.jsx +33 -35
- package/src/components/SpacingControl.jsx +5 -6
- package/src/components/index.js +18 -16
- package/src/filters/block-categories.js +50 -0
- package/src/filters/hide-root-block-for-other.js +53 -0
- package/src/filters/index.js +24 -0
- package/src/filters/inner-blocks-cleanup.jsx +53 -0
- package/src/filters/root-block.js +41 -0
- package/src/hooks/useTabs.jsx +2 -2
- package/src/icons/index.jsx +74 -38
- package/src/index.js +2 -0
- package/src/plugins/index.js +22 -0
- package/src/plugins/root-block-appender.jsx +51 -0
- package/src/plugins/root-pattern-appender.jsx +53 -0
- package/src/styles/{_empty-block-appender.scss → _empty-block-placeholder.scss} +6 -1
- package/src/styles/_root-block-appender.scss +13 -0
- package/src/styles/_root-pattern-appender.scss +58 -0
- package/src/styles/editor-canvas.scss +9 -3
- package/src/utils/helpers.js +53 -0
- package/src/utils/index.js +0 -3
- package/src/components/EmptyBlockAppender.jsx +0 -38
- package/src/utils/attributes.js +0 -252
- package/src/utils/filters.jsx +0 -40
- package/src/utils/rootBlock/appender.js +0 -62
- package/src/utils/rootBlock/hideRootBlockForInlineInserter.js +0 -24
- package/src/utils/rootBlock/index.js +0 -6
- package/src/utils/rootBlock/rootBlockVisibilityFilter.js +0 -35
- package/src/utils/rootBlock/setRootBlockFilter.js +0 -30
- package/src/utils/rootBlock/setRootBlockForPostTypes.js +0 -73
- package/src/utils/rootBlock/unsetRootBlockFilter.js +0 -26
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@secretstache/wordpress-gutenberg",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"author": "Secret Stache",
|
|
6
6
|
"license": "GPL-2.0-or-later",
|
|
@@ -41,10 +41,13 @@
|
|
|
41
41
|
"@wordpress/block-editor": "^14.19.0",
|
|
42
42
|
"@wordpress/blocks": "^14.13.0",
|
|
43
43
|
"@wordpress/components": "^29.10.0",
|
|
44
|
+
"@wordpress/compose": "^7.38.0",
|
|
44
45
|
"@wordpress/data": "^10.24.0",
|
|
45
46
|
"@wordpress/dom-ready": "^4.24.0",
|
|
46
47
|
"@wordpress/element": "^6.24.0",
|
|
47
48
|
"@wordpress/hooks": "^4.24.0",
|
|
49
|
+
"@wordpress/icons": "^11.5.0",
|
|
50
|
+
"@wordpress/plugins": "^7.38.0",
|
|
48
51
|
"babel-core": "^6.26.3",
|
|
49
52
|
"babel-loader": "^9.1.3",
|
|
50
53
|
"node-sass": "^9.0.0",
|
|
@@ -52,7 +55,7 @@
|
|
|
52
55
|
"react": "^18.0.0",
|
|
53
56
|
"react-dom": "^18.0.0",
|
|
54
57
|
"sass": "^1.90.0",
|
|
55
|
-
"vite": "^7.
|
|
58
|
+
"vite": "^7.3.1",
|
|
56
59
|
"vite-plugin-externals": "^0.6.2"
|
|
57
60
|
},
|
|
58
61
|
"dependencies": {
|
|
@@ -68,10 +71,13 @@
|
|
|
68
71
|
"@wordpress/block-editor": "^14.19.0",
|
|
69
72
|
"@wordpress/blocks": "^14.13.0",
|
|
70
73
|
"@wordpress/components": "^29.10.0",
|
|
74
|
+
"@wordpress/compose": "^7.38.0",
|
|
71
75
|
"@wordpress/data": "^10.24.0",
|
|
72
76
|
"@wordpress/dom-ready": "^4.24.0",
|
|
73
77
|
"@wordpress/element": "^6.24.0",
|
|
74
78
|
"@wordpress/hooks": "^4.24.0",
|
|
79
|
+
"@wordpress/icons": "^11.5.0",
|
|
80
|
+
"@wordpress/plugins": "^7.38.0",
|
|
75
81
|
"react": "^18.0.0",
|
|
76
82
|
"react-dom": "^18.0.0"
|
|
77
83
|
},
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { InnerBlocks } from '@wordpress/block-editor';
|
|
2
|
+
import { Icon, addTemplate } from '@wordpress/icons';
|
|
3
|
+
import { Button } from '@wordpress/components';
|
|
4
|
+
import classNames from 'classnames';
|
|
5
|
+
|
|
6
|
+
import { __experimentalPatternAppender as PatternAppender } from './PatternAppender.jsx';
|
|
7
|
+
|
|
8
|
+
export const __experimentalEmptyBlockPlaceholder = (props) => {
|
|
9
|
+
const {
|
|
10
|
+
title = 'This block is empty',
|
|
11
|
+
text = 'Use the "+" button below to add content blocks',
|
|
12
|
+
showIcon = true,
|
|
13
|
+
hasBlockAppender = true,
|
|
14
|
+
hasPatternAppender = true,
|
|
15
|
+
clientId,
|
|
16
|
+
isLight = false,
|
|
17
|
+
className,
|
|
18
|
+
} = props;
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<div className={classNames('empty-block-placeholder', className, { 'empty-block-placeholder--light': isLight })}>
|
|
22
|
+
<div className="empty-block-placeholder__content">
|
|
23
|
+
{
|
|
24
|
+
showIcon && (
|
|
25
|
+
<svg className="empty-block-placeholder__icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
|
|
26
|
+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 13h6m-3-3v6m5 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
|
|
27
|
+
</svg>
|
|
28
|
+
)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
<h3 className="empty-block-placeholder__title">{title}</h3>
|
|
32
|
+
<p className="empty-block-placeholder__text">{text}</p>
|
|
33
|
+
</div>
|
|
34
|
+
|
|
35
|
+
<div className="empty-block-placeholder__buttons-wrapper">
|
|
36
|
+
{
|
|
37
|
+
hasBlockAppender && (
|
|
38
|
+
<div className="empty-block-placeholder__button">
|
|
39
|
+
<InnerBlocks.ButtonBlockAppender />
|
|
40
|
+
</div>
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
{
|
|
45
|
+
hasPatternAppender && (
|
|
46
|
+
<div className="empty-block-placeholder__button">
|
|
47
|
+
<PatternAppender
|
|
48
|
+
render={({ setModalOpen }) => (
|
|
49
|
+
<Button
|
|
50
|
+
__next40pxDefaultSize
|
|
51
|
+
className="block-editor-button-block-appender"
|
|
52
|
+
onClick={() => setModalOpen(true)}
|
|
53
|
+
label="Add Pattern"
|
|
54
|
+
showTooltip
|
|
55
|
+
>
|
|
56
|
+
<Icon icon={addTemplate} />
|
|
57
|
+
</Button>
|
|
58
|
+
)}
|
|
59
|
+
rootClientId={clientId}
|
|
60
|
+
/>
|
|
61
|
+
</div>
|
|
62
|
+
)
|
|
63
|
+
}
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
);
|
|
67
|
+
};
|
|
@@ -3,9 +3,8 @@ import {
|
|
|
3
3
|
MediaUpload,
|
|
4
4
|
MediaUploadCheck,
|
|
5
5
|
} from '@wordpress/block-editor';
|
|
6
|
-
import { Button
|
|
7
|
-
|
|
8
|
-
import { editIcon, trashIcon } from '../icons/index.jsx';
|
|
6
|
+
import { Button } from '@wordpress/components';
|
|
7
|
+
import { Icon, pencil, trash } from '@wordpress/icons';
|
|
9
8
|
|
|
10
9
|
export const IconPicker = ({ imageId, imageUrl, imageAlt, svgCode, onSelect, onRemove }) => {
|
|
11
10
|
const hasImage = imageId && imageUrl;
|
|
@@ -38,7 +37,7 @@ export const IconPicker = ({ imageId, imageUrl, imageAlt, svgCode, onSelect, onR
|
|
|
38
37
|
onClick={open}
|
|
39
38
|
>
|
|
40
39
|
<Icon
|
|
41
|
-
icon={
|
|
40
|
+
icon={pencil}
|
|
42
41
|
size={20}
|
|
43
42
|
className="bc-image-wrapper__btn-icon"
|
|
44
43
|
/>
|
|
@@ -50,7 +49,7 @@ export const IconPicker = ({ imageId, imageUrl, imageAlt, svgCode, onSelect, onR
|
|
|
50
49
|
onClick={onRemove}
|
|
51
50
|
>
|
|
52
51
|
<Icon
|
|
53
|
-
icon={
|
|
52
|
+
icon={trash}
|
|
54
53
|
size={20}
|
|
55
54
|
className="bc-image-wrapper__btn-icon"
|
|
56
55
|
/>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { BaseControl, Button, FocalPointPicker
|
|
1
|
+
import { BaseControl, Button, FocalPointPicker } from '@wordpress/components';
|
|
2
|
+
import { Icon, page } from '@wordpress/icons';
|
|
2
3
|
import { MediaUpload, MediaUploadCheck } from '@wordpress/block-editor';
|
|
3
4
|
|
|
4
|
-
import { pageIcon } from '../icons/index.jsx';
|
|
5
5
|
import { MEDIA_TYPE } from '../utils/index.js';
|
|
6
6
|
|
|
7
7
|
export const ImageRenderer = ({
|
|
@@ -27,7 +27,7 @@ export const ImageRenderer = ({
|
|
|
27
27
|
<Button
|
|
28
28
|
className="bc-remove-btn"
|
|
29
29
|
onClick={onRemoveClick}
|
|
30
|
-
|
|
30
|
+
variant="secondary"
|
|
31
31
|
isDestructive
|
|
32
32
|
>
|
|
33
33
|
{removeButtonLabel}
|
|
@@ -61,7 +61,7 @@ export const VideoRenderer = ({
|
|
|
61
61
|
<Button
|
|
62
62
|
className="bc-remove-btn"
|
|
63
63
|
onClick={onRemoveClick}
|
|
64
|
-
|
|
64
|
+
variant="secondary"
|
|
65
65
|
isDestructive
|
|
66
66
|
>
|
|
67
67
|
{removeButtonLabel}
|
|
@@ -90,7 +90,7 @@ export const AnimationRenderer = ({
|
|
|
90
90
|
return animationFileId && animationFileUrl ? (
|
|
91
91
|
<>
|
|
92
92
|
<div className="bc-animation-block-json-file" onClick={onSelectClick}>
|
|
93
|
-
<
|
|
93
|
+
<Icon icon={page} size={36} />
|
|
94
94
|
<span>{animationFileName}</span>
|
|
95
95
|
</div>
|
|
96
96
|
<Button
|
|
@@ -158,16 +158,15 @@ export const MediaControl = ({
|
|
|
158
158
|
|
|
159
159
|
{
|
|
160
160
|
hasFocalPoint && mediaId && mediaUrl && (
|
|
161
|
-
<
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
</BaseControl>
|
|
161
|
+
<FocalPointPicker
|
|
162
|
+
__nextHasNoMarginBottom
|
|
163
|
+
label={focalPointLabel}
|
|
164
|
+
url={mediaUrl}
|
|
165
|
+
value={focalPoint}
|
|
166
|
+
onDragStart={onFocalPointChange}
|
|
167
|
+
onDrag={onFocalPointChange}
|
|
168
|
+
onChange={onFocalPointChange}
|
|
169
|
+
/>
|
|
171
170
|
)
|
|
172
171
|
}
|
|
173
172
|
</>
|
|
@@ -36,7 +36,7 @@ export const MediaWithFocalPointControl = memo(({
|
|
|
36
36
|
|
|
37
37
|
[focalPointAttributeName]: { x: 0.5, y: 0.5 }
|
|
38
38
|
});
|
|
39
|
-
}, [ mediaAttributeName ]);
|
|
39
|
+
}, [ mediaAttributeName, focalPointAttributeName ]);
|
|
40
40
|
|
|
41
41
|
const onMediaRemove = useCallback(() => {
|
|
42
42
|
setAttributes({
|
|
@@ -62,16 +62,15 @@ export const MediaWithFocalPointControl = memo(({
|
|
|
62
62
|
</BaseControl>
|
|
63
63
|
|
|
64
64
|
{media?.url && (
|
|
65
|
-
<
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
</BaseControl>
|
|
65
|
+
<FocalPointPicker
|
|
66
|
+
__nextHasNoMarginBottom
|
|
67
|
+
label={focalPointLabel}
|
|
68
|
+
url={media.url}
|
|
69
|
+
value={focalPoint}
|
|
70
|
+
onDragStart={onFocalPointChange}
|
|
71
|
+
onDrag={onFocalPointChange}
|
|
72
|
+
onChange={onFocalPointChange}
|
|
73
|
+
/>
|
|
75
74
|
)}
|
|
76
75
|
</>
|
|
77
76
|
);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { useState } from '@wordpress/element';
|
|
2
|
+
|
|
3
|
+
import { __experimentalPatternsModal as PatternsModal } from './PatternsModal.jsx';
|
|
4
|
+
|
|
5
|
+
export const __experimentalPatternAppender = (props) => {
|
|
6
|
+
const { render, rootClientId } = props;
|
|
7
|
+
|
|
8
|
+
const [ isModalOpen, setModalOpen ] = useState(false);
|
|
9
|
+
|
|
10
|
+
return (
|
|
11
|
+
<>
|
|
12
|
+
{ render({ isModalOpen, setModalOpen }) }
|
|
13
|
+
|
|
14
|
+
{
|
|
15
|
+
isModalOpen && (
|
|
16
|
+
<PatternsModal
|
|
17
|
+
onClose={() => setModalOpen(false)}
|
|
18
|
+
rootClientId={rootClientId}
|
|
19
|
+
/>
|
|
20
|
+
)
|
|
21
|
+
}
|
|
22
|
+
</>
|
|
23
|
+
);
|
|
24
|
+
};
|
|
@@ -1,24 +1,22 @@
|
|
|
1
|
-
import { useDispatch, useSelect } from '@wordpress/data';
|
|
2
|
-
import {
|
|
3
|
-
import { rawHandler } from '@wordpress/blocks';
|
|
1
|
+
import { useDispatch, useSelect, select } from '@wordpress/data';
|
|
2
|
+
import { cloneBlock, createBlock, rawHandler } from '@wordpress/blocks';
|
|
4
3
|
import { Button, Modal, TextControl } from '@wordpress/components';
|
|
4
|
+
import { useMemo, useState } from '@wordpress/element';
|
|
5
5
|
import { __experimentalBlockPatternsList as BlockPatternsList } from '@wordpress/block-editor';
|
|
6
6
|
|
|
7
|
-
export const
|
|
7
|
+
export const __experimentalPatternsModal = ({ onClose, rootClientId }) => {
|
|
8
8
|
const patterns = useSelect(
|
|
9
|
-
(select) => select('core/block-editor').__experimentalGetAllowedPatterns?.(rootClientId)
|
|
10
|
-
[rootClientId]
|
|
9
|
+
(select) => select('core/block-editor').__experimentalGetAllowedPatterns?.(rootClientId),
|
|
10
|
+
[ rootClientId ]
|
|
11
11
|
);
|
|
12
12
|
|
|
13
|
-
const { insertBlocks
|
|
14
|
-
const
|
|
15
|
-
selectedClientId: select('core/block-editor').getSelectedBlockClientId(),
|
|
16
|
-
}), []);
|
|
13
|
+
const { insertBlocks } = useDispatch('core/block-editor');
|
|
14
|
+
const getBlockOrder = select('core/block-editor').getBlockOrder;
|
|
17
15
|
|
|
18
16
|
const [ searchValue, setSearchValue ] = useState('');
|
|
19
17
|
const [ selectedCategory, setSelectedCategory ] = useState('all');
|
|
20
18
|
|
|
21
|
-
const normalizedPatterns = (patterns || []).map((pattern, index) => ({
|
|
19
|
+
const normalizedPatterns = useMemo(() => (patterns || []).map((pattern, index) => ({
|
|
22
20
|
...pattern,
|
|
23
21
|
name: typeof pattern?.name === 'string' ? pattern.name : `pattern-${index}`,
|
|
24
22
|
title: typeof pattern?.title === 'string'
|
|
@@ -29,7 +27,7 @@ export const PatternsModal = ({ isOpen, onRequestClose, rootClientId }) => {
|
|
|
29
27
|
: typeof pattern?.content === 'string'
|
|
30
28
|
? rawHandler({ HTML: pattern.content })
|
|
31
29
|
: [],
|
|
32
|
-
}));
|
|
30
|
+
})), [ patterns ]);
|
|
33
31
|
|
|
34
32
|
const categories = [
|
|
35
33
|
{ name: 'all', label: 'All Patterns' },
|
|
@@ -39,39 +37,39 @@ export const PatternsModal = ({ isOpen, onRequestClose, rootClientId }) => {
|
|
|
39
37
|
})),
|
|
40
38
|
];
|
|
41
39
|
|
|
42
|
-
const filteredPatterns =
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
const filteredPatterns = useMemo(() => {
|
|
41
|
+
return normalizedPatterns.filter((pattern) => {
|
|
42
|
+
const matchesSearch = !searchValue || (pattern.title || '').toLowerCase().includes(searchValue.toLowerCase());
|
|
43
|
+
const inCategory = selectedCategory === 'all' || (pattern.categories || []).includes(selectedCategory);
|
|
45
44
|
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
return matchesSearch && inCategory;
|
|
46
|
+
});
|
|
47
|
+
}, [ normalizedPatterns, searchValue, selectedCategory ]);
|
|
48
48
|
|
|
49
49
|
const onClickPattern = (pattern) => {
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
:
|
|
53
|
-
|
|
54
|
-
|
|
50
|
+
const isSyncedUserPattern = pattern?.type === 'user' && pattern?.syncStatus !== 'unsynced' && !!pattern?.id;
|
|
51
|
+
const blocks = isSyncedUserPattern
|
|
52
|
+
? [createBlock('core/block', { ref: pattern.id })]
|
|
53
|
+
: Array.isArray(pattern.blocks)
|
|
54
|
+
? pattern.blocks.map((block) => cloneBlock(block))
|
|
55
|
+
: typeof pattern.content === 'string'
|
|
56
|
+
? rawHandler({ HTML: pattern.content })
|
|
57
|
+
: [];
|
|
55
58
|
|
|
56
|
-
const
|
|
57
|
-
const targetClientId =
|
|
59
|
+
const isInsideBlock = rootClientId !== null && rootClientId !== undefined;
|
|
60
|
+
const targetClientId = isInsideBlock ? rootClientId : undefined;
|
|
61
|
+
const blockOrder = isInsideBlock ? getBlockOrder(targetClientId) : getBlockOrder();
|
|
62
|
+
const insertIndex = Array.isArray(blockOrder) ? blockOrder.length : 0;
|
|
58
63
|
|
|
59
|
-
|
|
60
|
-
replaceBlock(targetClientId, blocks);
|
|
61
|
-
} else {
|
|
62
|
-
insertBlocks(blocks, 0, targetClientId);
|
|
63
|
-
}
|
|
64
|
-
onRequestClose();
|
|
65
|
-
};
|
|
64
|
+
insertBlocks(blocks, insertIndex, targetClientId);
|
|
66
65
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}
|
|
66
|
+
onClose();
|
|
67
|
+
};
|
|
70
68
|
|
|
71
69
|
return (
|
|
72
70
|
<Modal
|
|
73
71
|
title="Patterns"
|
|
74
|
-
onRequestClose={
|
|
72
|
+
onRequestClose={onClose}
|
|
75
73
|
isFullScreen
|
|
76
74
|
>
|
|
77
75
|
<div className="block-editor-block-patterns-explorer">
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { RangeControl, Tooltip } from '@wordpress/components';
|
|
2
2
|
import { useCallback } from '@wordpress/element';
|
|
3
|
-
|
|
4
|
-
import { sidesBottomIcon, sidesTopIcon } from '../icons/index.jsx';
|
|
3
|
+
import { sidesBottom, sidesTop } from '@wordpress/icons';
|
|
5
4
|
|
|
6
5
|
const generateMarks = (min, max) => [
|
|
7
6
|
{ value: min, label: min === -1 ? 'Default' : min.toString() },
|
|
@@ -78,7 +77,7 @@ export const SpacingControl = ({
|
|
|
78
77
|
onChange={handleChange('margin', 'top')}
|
|
79
78
|
disabled={disabledMargin.top}
|
|
80
79
|
tooltip={marginTooltips.top}
|
|
81
|
-
afterIcon={
|
|
80
|
+
afterIcon={sidesTop}
|
|
82
81
|
withInputField={false}
|
|
83
82
|
/>
|
|
84
83
|
|
|
@@ -90,7 +89,7 @@ export const SpacingControl = ({
|
|
|
90
89
|
onChange={handleChange('margin', 'bottom')}
|
|
91
90
|
disabled={disabledMargin.bottom}
|
|
92
91
|
tooltip={marginTooltips.bottom}
|
|
93
|
-
afterIcon={
|
|
92
|
+
afterIcon={sidesBottom}
|
|
94
93
|
withInputField={false}
|
|
95
94
|
/>
|
|
96
95
|
</>
|
|
@@ -106,7 +105,7 @@ export const SpacingControl = ({
|
|
|
106
105
|
onChange={handleChange('padding', 'top')}
|
|
107
106
|
disabled={disabledPadding.top}
|
|
108
107
|
tooltip={paddingTooltips.top}
|
|
109
|
-
afterIcon={
|
|
108
|
+
afterIcon={sidesTop}
|
|
110
109
|
withInputField={false}
|
|
111
110
|
/>
|
|
112
111
|
|
|
@@ -118,7 +117,7 @@ export const SpacingControl = ({
|
|
|
118
117
|
onChange={handleChange('padding', 'bottom')}
|
|
119
118
|
disabled={disabledPadding.bottom}
|
|
120
119
|
tooltip={paddingTooltips.bottom}
|
|
121
|
-
afterIcon={
|
|
120
|
+
afterIcon={sidesBottom}
|
|
122
121
|
withInputField={false}
|
|
123
122
|
/>
|
|
124
123
|
</>
|
package/src/components/index.js
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
3
|
-
export
|
|
4
|
-
export
|
|
5
|
-
export
|
|
6
|
-
export
|
|
7
|
-
export
|
|
8
|
-
export
|
|
9
|
-
export
|
|
10
|
-
export
|
|
11
|
-
export
|
|
12
|
-
export
|
|
13
|
-
export
|
|
14
|
-
export
|
|
15
|
-
export
|
|
16
|
-
export
|
|
1
|
+
export * from './ColorPaletteControl.jsx';
|
|
2
|
+
export * from './IconPicker.jsx';
|
|
3
|
+
export * from './ImageActions.jsx';
|
|
4
|
+
export * from './LinkControl.jsx';
|
|
5
|
+
export * from './MediaControl.jsx';
|
|
6
|
+
export * from './SortableSelect.jsx';
|
|
7
|
+
export * from './DataQueryControls.jsx';
|
|
8
|
+
export * from './SpacingControl.jsx';
|
|
9
|
+
export * from './ResponsiveSpacingControl.jsx';
|
|
10
|
+
export * from './ResourcesWrapper.jsx';
|
|
11
|
+
export * from './DividersControl.jsx';
|
|
12
|
+
export * from './MediaTypeControl.jsx';
|
|
13
|
+
export * from './InsertBlockToolbar.jsx';
|
|
14
|
+
export * from './PreviewControl.jsx';
|
|
15
|
+
export * from './MediaWithFocalPointControl.jsx';
|
|
16
|
+
export * from './EmptyBlockPlaceholder.jsx';
|
|
17
|
+
export * from './PatternAppender.jsx';
|
|
18
|
+
export * from './PatternsModal.jsx';
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { addFilter, removeFilter } from '@wordpress/hooks';
|
|
2
|
+
|
|
3
|
+
export class BlockCategoriesFilter {
|
|
4
|
+
name = 'ssm/block-categories';
|
|
5
|
+
isAdded = false;
|
|
6
|
+
|
|
7
|
+
constructor(
|
|
8
|
+
categories = {},
|
|
9
|
+
postTypes = ['page', 'post', 'ssm_design_system', 'wp_block'],
|
|
10
|
+
) {
|
|
11
|
+
this.categories = categories;
|
|
12
|
+
this.postTypes = postTypes;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
add() {
|
|
16
|
+
addFilter(
|
|
17
|
+
'blocks.registerBlockType',
|
|
18
|
+
'ssm/block-categories',
|
|
19
|
+
(settings, name) => {
|
|
20
|
+
const movedBlocks = Object.values(this.categories).flat();
|
|
21
|
+
|
|
22
|
+
if (!movedBlocks.includes(name)) {
|
|
23
|
+
return settings;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
let newCategoryName = '';
|
|
27
|
+
|
|
28
|
+
for (const [category, blocks] of Object.entries(this.categories)) {
|
|
29
|
+
if (blocks.includes(name)) {
|
|
30
|
+
newCategoryName = category;
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return {
|
|
36
|
+
...settings,
|
|
37
|
+
'category': newCategoryName,
|
|
38
|
+
};
|
|
39
|
+
},
|
|
40
|
+
10,
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
this.isAdded = true;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
remove() {
|
|
47
|
+
removeFilter('blocks.registerBlockType', this.name);
|
|
48
|
+
this.isAdded = false;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { addFilter, removeFilter } from '@wordpress/hooks';
|
|
2
|
+
import { getBlockTypes } from '@wordpress/blocks';
|
|
3
|
+
|
|
4
|
+
export class HideRootBlockForOtherFilter {
|
|
5
|
+
name = 'ssm/hide-root-block-for-other';
|
|
6
|
+
isAdded = false;
|
|
7
|
+
|
|
8
|
+
constructor(
|
|
9
|
+
rootBlockName = 'ssm/section-wrapper',
|
|
10
|
+
postTypes = ['page', 'post', 'ssm_design_system', 'wp_block'],
|
|
11
|
+
) {
|
|
12
|
+
this.rootBlockName = rootBlockName;
|
|
13
|
+
this.postTypes = postTypes;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
add() {
|
|
17
|
+
addFilter(
|
|
18
|
+
'blocks.registerBlockType',
|
|
19
|
+
this.name,
|
|
20
|
+
(blockSettings, blockName) => {
|
|
21
|
+
const isRootBlock = blockName === this.rootBlockName;
|
|
22
|
+
const isBaseBlock = blockName === 'core/block';
|
|
23
|
+
const hasOwnAllowedBlocks = !!blockSettings?.allowedBlocks;
|
|
24
|
+
|
|
25
|
+
// skip specific blocks
|
|
26
|
+
if (isRootBlock || isBaseBlock || hasOwnAllowedBlocks) {
|
|
27
|
+
return blockSettings;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// get all blocks
|
|
31
|
+
const allowedBlocks = getBlockTypes()
|
|
32
|
+
?.filter((block) => {
|
|
33
|
+
const isRootBlock = block.name === this.rootBlockName;
|
|
34
|
+
const hasParent = !!block?.parent;
|
|
35
|
+
|
|
36
|
+
return !isRootBlock && !hasParent;
|
|
37
|
+
})
|
|
38
|
+
?.map((block) => block.name);
|
|
39
|
+
|
|
40
|
+
blockSettings.allowedBlocks = allowedBlocks;
|
|
41
|
+
|
|
42
|
+
return blockSettings;
|
|
43
|
+
},
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
this.isAdded = true;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
remove() {
|
|
50
|
+
removeFilter('blocks.registerBlockType', this.name);
|
|
51
|
+
this.isAdded = false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { dispatch } from '@wordpress/data';
|
|
2
|
+
|
|
3
|
+
export * from './hide-root-block-for-other.js';
|
|
4
|
+
export * from './inner-blocks-cleanup.jsx';
|
|
5
|
+
export * from './root-block.js';
|
|
6
|
+
export * from './block-categories.js';
|
|
7
|
+
|
|
8
|
+
export const setPostTypeFilters = (filters, currentPostType, onSet) => {
|
|
9
|
+
if (!filters || !currentPostType) return;
|
|
10
|
+
|
|
11
|
+
filters?.forEach((filter) => {
|
|
12
|
+
if (filter.isAdded) {
|
|
13
|
+
filter.remove();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (filter.postTypes.includes(currentPostType)) {
|
|
17
|
+
filter.add();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
dispatch('core/blocks').reapplyBlockTypeFilters();
|
|
21
|
+
|
|
22
|
+
if (onSet) onSet();
|
|
23
|
+
});
|
|
24
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { createHigherOrderComponent } from '@wordpress/compose';
|
|
2
|
+
import { dispatch, select, useSelect } from '@wordpress/data';
|
|
3
|
+
import { useEffect } from '@wordpress/element';
|
|
4
|
+
import { addFilter, removeFilter } from '@wordpress/hooks';
|
|
5
|
+
|
|
6
|
+
export class InnerBlocksCleanupFilter {
|
|
7
|
+
name = 'ssm/inner-blocks-cleanup';
|
|
8
|
+
isAdded = false;
|
|
9
|
+
|
|
10
|
+
constructor(blockName) {
|
|
11
|
+
this.blockName = blockName;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
add() {
|
|
15
|
+
addFilter(
|
|
16
|
+
'editor.BlockEdit',
|
|
17
|
+
this.name,
|
|
18
|
+
createHigherOrderComponent((BlockEdit) => (props) => {
|
|
19
|
+
const { clientId, attributes, name } = props;
|
|
20
|
+
|
|
21
|
+
const { dataSource } = attributes;
|
|
22
|
+
|
|
23
|
+
if (name !== this.blockName) {
|
|
24
|
+
return <BlockEdit {...props} />;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const innerBlocks = useSelect(
|
|
28
|
+
(select) => select('core/block-editor').getBlock(clientId)?.innerBlocks || [],
|
|
29
|
+
[]
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
if (dataSource !== 'none' && innerBlocks.length > 0) {
|
|
34
|
+
dispatch('core/block-editor').updateBlock(clientId, {
|
|
35
|
+
...select('core/block-editor').getBlock(clientId),
|
|
36
|
+
innerBlocks: [],
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}, [ dataSource, innerBlocks.length ]);
|
|
40
|
+
|
|
41
|
+
return <BlockEdit {...props} />;
|
|
42
|
+
}, this.name),
|
|
43
|
+
10,
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
this.isAdded = true;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
remove() {
|
|
50
|
+
removeFilter('editor.BlockEdit', this.name);
|
|
51
|
+
this.isAdded = false;
|
|
52
|
+
}
|
|
53
|
+
}
|