PluginProbe
Content Blocks Builder – Create blocks, repeater blocks with carousel, grid, popup layouts / trunk
Content Blocks Builder – Create blocks, repeater blocks with carousel, grid, popup layouts vtrunk
2.8.14 2.8.13 2.8.12 2.7.5 2.7.6 2.7.7 2.7.8 2.7.9 2.8.0 2.8.1 2.8.10 2.8.11 2.8.2 2.8.3 2.8.4 2.8.5 2.8.6 2.8.7 2.8.8 2.8.9 trunk 1.0.1 1.0.2 1.1.0 1.1.1 All 147 releases
content-blocks-builder / src / custom-blocks / hooks.js

hooks.js in Content Blocks Builder – Create blocks, repeater blocks with carousel, grid, popup layouts trunk, at src/custom-blocks/hooks.js

204 lines 5.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * External dependencies
3 */
4 import { isEmpty, pick } from "lodash";
5 import { __ } from "@wordpress/i18n";
6
7 /**
8 * WordPress dependencies
9 */
10 import {
11 BlockControls,
12 InspectorControls,
13 ButtonBlockAppender,
14 } from "@wordpress/block-editor";
15 import { SelectControl } from "@wordpress/components";
16 import { addFilter } from "@wordpress/hooks";
17 import { hasBlockSupport } from "@wordpress/blocks";
18
19 /**
20 * Internal dependencies
21 */
22 import {
23 getCoreFeatures,
24 boldblocksHasSupport,
25 useStyleBlockControls,
26 } from "../utils";
27
28 /**
29 * Add a button on the parent block's toolbar to add child blocks
30 */
31 addFilter(
32 "boldblocks.edit.blockEditInner",
33 `boldblocks/blockEditInner/addChildBlock`,
34 (content, props) => {
35 const layoutType = boldblocksHasSupport(props.name, "layoutType");
36 if (!["carousel", "grid", "accordion", "vstack"].includes(layoutType)) {
37 return content;
38 }
39
40 const { isSelected, clientId } = props;
41
42 return (
43 <>
44 {content}
45 {isSelected && (
46 <BlockControls group="block">
47 <ButtonBlockAppender
48 rootClientId={clientId}
49 className="repeater-add-item"
50 />
51 </BlockControls>
52 )}
53 </>
54 );
55 },
56 );
57
58 /**
59 * HTML element
60 */
61 addFilter(
62 "boldblocks.edit.blockEditInner",
63 `boldblocks/blockEditInner/tagName`,
64 (content, props) => {
65 if ("standalone" !== boldblocksHasSupport(props.name, "layoutType")) {
66 return content;
67 }
68
69 const displayBlockControls = useStyleBlockControls();
70
71 const {
72 isSelected,
73 attributes: { tagName = "div" },
74 setAttributes,
75 } = props;
76
77 return (
78 <>
79 {content}
80 {isSelected && displayBlockControls && (
81 <InspectorControls group="advanced">
82 <SelectControl
83 __next40pxDefaultSize
84 label={__("HTML element", "content-blocks-builder")}
85 options={[
86 { label: "<div>", value: "div" },
87 { label: "<main>", value: "main" },
88 { label: "<aside>", value: "aside" },
89 { label: "<section>", value: "section" },
90 { label: "<article>", value: "article" },
91 { label: "<header>", value: "header" },
92 { label: "<footer>", value: "footer" },
93 { label: "<nav>", value: "nav" },
94 { label: "<blockquote>", value: "blockquote" },
95 { label: "<a>", value: "a" },
96 ]}
97 value={tagName}
98 onChange={(tagName) => setAttributes({ tagName })}
99 help={
100 tagName === "a"
101 ? __(
102 "Don’t nest links inside this block. Use Custom Attributes to set href, target, and rel.",
103 "content-blocks-builder",
104 )
105 : null
106 }
107 />
108 </InspectorControls>
109 )}
110 </>
111 );
112 },
113 );
114
115 /**
116 * Force block support for core features on CBB blocks
117 */
118 addFilter(
119 "blockEditor.useSetting.before",
120 "boldblocks/CBB/useSetting.before",
121 (settingValue, settingName, clientId, blockName) => {
122 if (!hasBlockSupport(blockName, "cbb")) {
123 return settingValue;
124 }
125
126 // Force color attributes
127 if (
128 ["color.text", "color.background", "color.link"].includes(settingName)
129 ) {
130 return true;
131 }
132
133 if (
134 [
135 "spacing.padding",
136 "spacing.margin",
137 "spacing.blockGap",
138 "dimensions.minHeight",
139 ].includes(settingName)
140 ) {
141 const layoutType = boldblocksHasSupport(blockName, "layoutType");
142 const supports = getCoreFeatures(layoutType) ?? {};
143
144 if (!isEmpty(pick(supports, settingName))) {
145 return true;
146 }
147 }
148
149 return settingValue;
150 },
151 );
152
153 const AllowedInnerBlocks = (CBBBlocks?.blocks ?? []).reduce((prev, current) => {
154 const { name, blockParent, blockAncestor } = current?.parent
155 ? current.parent
156 : current;
157
158 [blockParent, blockAncestor].forEach((blockNames) => {
159 if (blockNames?.length) {
160 blockNames.forEach((blockName) => {
161 if (!blockName.startsWith("boldblocks/")) {
162 if (!(prev[blockName] ?? false)) {
163 prev[blockName] = [name];
164 } else {
165 if (!prev[blockName].includes(name)) {
166 prev[blockName].push(name);
167 }
168 }
169 }
170 });
171 }
172 });
173
174 return prev;
175 }, {});
176
177 const AllowedBlockNames = Object.keys(AllowedInnerBlocks);
178 if (AllowedBlockNames?.length) {
179 addFilter(
180 "blocks.registerBlockType",
181 "boldblocks/CBB/overrideAllowedBlocks",
182 (blockSettings, blockName) => {
183 if (
184 !blockSettings.allowedBlocks?.length ||
185 blockSettings?.supports?.cbb
186 ) {
187 return blockSettings;
188 }
189
190 if (AllowedBlockNames?.includes(blockName)) {
191 return {
192 ...blockSettings,
193 allowedBlocks: [
194 ...blockSettings.allowedBlocks,
195 ...AllowedInnerBlocks[blockName],
196 ],
197 };
198 }
199
200 return blockSettings;
201 },
202 );
203 }
204