PluginProbe
Block Animations, Motion & Scroll Effects – Ghost Kit / 3.4.1
Block Animations, Motion & Scroll Effects – Ghost Kit v3.4.1
3.7.2 3.7.1 3.7.0 3.6.1 trunk 1.6.3 2.25.0 3.3.0 3.3.1 3.3.2 3.3.3 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.4.6 3.5.0 3.5.1 3.6.0
ghostkit / gutenberg / blocks / grid / edit.js

edit.js in Block Animations, Motion & Scroll Effects – Ghost Kit 3.4.1, at gutenberg/blocks/grid/edit.js

406 lines 9.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import classnames from 'classnames/dedupe';
2
3 import {
4 BlockControls,
5 InspectorControls,
6 useBlockProps,
7 useInnerBlocksProps,
8 } from '@wordpress/block-editor';
9 import { createBlock } from '@wordpress/blocks';
10 import {
11 Button,
12 PanelBody,
13 Placeholder,
14 ToolbarButton,
15 ToolbarGroup,
16 } from '@wordpress/components';
17 import { useDispatch, useSelect } from '@wordpress/data';
18 import { applyFilters } from '@wordpress/hooks';
19 import { __ } from '@wordpress/i18n';
20
21 import ApplyFilters from '../../components/apply-filters';
22 import GapSettings from '../../components/gap-settings';
23 import RangeControl from '../../components/range-control';
24 import ToggleGroup from '../../components/toggle-group';
25 import getIcon from '../../utils/get-icon';
26
27 /**
28 * Block Edit Class.
29 *
30 * @param props
31 */
32 export default function BlockEdit(props) {
33 const { clientId, attributes, setAttributes } = props;
34
35 const {
36 gap,
37 gapCustom,
38 gapVerticalCustom,
39 verticalAlign,
40 horizontalAlign,
41 } = attributes;
42
43 const { removeBlock, replaceInnerBlocks } =
44 useDispatch('core/block-editor');
45
46 const { getBlocks, columnsCount } = useSelect((select) => {
47 const { getBlockCount } = select('core/block-editor');
48
49 return {
50 getBlocks: select('core/block-editor').getBlocks,
51 columnsCount: getBlockCount(clientId),
52 };
53 // eslint-disable-next-line react-hooks/exhaustive-deps
54 }, []);
55
56 /**
57 * Get columns sizes array from layout string
58 *
59 * @param {string} layout - layout data. Example: `3-6-3`
60 *
61 * @return {Array}.
62 */
63 function getColumnsFromLayout(layout) {
64 const result = [];
65 const columnsData = layout.split('-');
66
67 columnsData.forEach((col) => {
68 const colAttrs = {
69 size: col,
70 };
71
72 if (col === 'a') {
73 colAttrs.size = 'auto';
74 } else if (col === 'g') {
75 colAttrs.size = 'grow';
76 }
77
78 // responsive.
79 if (columnsData.length === 2) {
80 colAttrs.md_size = '12';
81 }
82 if (columnsData.length === 3) {
83 colAttrs.lg_size = '12';
84 }
85 if (columnsData.length === 4) {
86 colAttrs.md_size = '12';
87 colAttrs.lg_size = '6';
88 }
89 if (columnsData.length === 5) {
90 colAttrs.sm_size = '12';
91 colAttrs.md_size = '5';
92 colAttrs.lg_size = '4';
93 }
94 if (columnsData.length === 6) {
95 colAttrs.sm_size = '6';
96 colAttrs.md_size = '4';
97 colAttrs.lg_size = '3';
98 }
99
100 result.push(colAttrs);
101 });
102
103 return result;
104 }
105
106 /**
107 * Select predefined layout.
108 *
109 * @param {string} layout layout string.
110 */
111 function onLayoutSelect(layout) {
112 const columnsData = getColumnsFromLayout(layout);
113 const newInnerBlocks = [];
114
115 columnsData.forEach((colAttrs) => {
116 newInnerBlocks.push(createBlock('ghostkit/grid-column', colAttrs));
117 });
118
119 replaceInnerBlocks(clientId, newInnerBlocks, false);
120 }
121
122 /**
123 * Layouts selector when no columns selected.
124 *
125 * @return {jsx}.
126 */
127 function LayoutsSelector() {
128 let layouts = [
129 '12',
130 '6-6',
131 '4-4-4',
132 '3-3-3-3',
133
134 '5-7',
135 '7-5',
136 '3-3-6',
137 '3-6-3',
138
139 '6-3-3',
140 '2-8-2',
141 'g-g-g-g-g',
142 '2-2-2-2-2-2',
143 ];
144 layouts = applyFilters('ghostkit.editor.grid.layouts', layouts, props);
145
146 const templatesModal = applyFilters(
147 'ghostkit.editor.grid.templatesModal',
148 '',
149 props
150 );
151
152 return (
153 <Placeholder
154 icon={getIcon('block-grid')}
155 label={__('Advanced Columns', 'ghostkit')}
156 instructions={__(
157 'Select one layout to get started.',
158 'ghostkit'
159 )}
160 className="ghostkit-select-layout"
161 >
162 <div className="ghostkit-grid-layout-preview">
163 {layouts.map((layout) => {
164 const columnsData = getColumnsFromLayout(layout);
165
166 return (
167 <Button
168 key={`layout-${layout}`}
169 className="ghostkit-grid-layout-preview-btn ghostkit-grid"
170 onClick={() => onLayoutSelect(layout)}
171 >
172 {columnsData.map((colAttrs, i) => {
173 const colName = `layout-${layout}-col-${i}`;
174
175 return (
176 <div
177 key={colName}
178 className={classnames(
179 'ghostkit-col',
180 `ghostkit-col-${colAttrs.size}`
181 )}
182 />
183 );
184 })}
185 </Button>
186 );
187 })}
188 </div>
189 {templatesModal}
190 </Placeholder>
191 );
192 }
193
194 /**
195 * Updates the column count
196 *
197 * @param {number} newColumns New column count.
198 */
199 function updateColumns(newColumns) {
200 // Remove Grid block.
201 if (newColumns < 1) {
202 removeBlock(clientId);
203
204 // Add new columns.
205 } else if (newColumns > columnsCount) {
206 const newCount = newColumns - columnsCount;
207 const newInnerBlocks = [...getBlocks(clientId)];
208
209 for (let i = 1; i <= newCount; i += 1) {
210 newInnerBlocks.push(
211 createBlock('ghostkit/grid-column', { size: 3 })
212 );
213 }
214
215 replaceInnerBlocks(clientId, newInnerBlocks, false);
216
217 // Remove columns.
218 } else if (newColumns < columnsCount) {
219 const newInnerBlocks = [...getBlocks(clientId)];
220 newInnerBlocks.splice(newColumns, columnsCount - newColumns);
221
222 replaceInnerBlocks(clientId, newInnerBlocks, false);
223 }
224 }
225
226 let className = classnames(
227 'ghostkit-grid',
228 `ghostkit-grid-gap-${gap}`,
229 verticalAlign ? `ghostkit-grid-align-items-${verticalAlign}` : false,
230 horizontalAlign
231 ? `ghostkit-grid-justify-content-${horizontalAlign}`
232 : false
233 );
234
235 // background
236 const background = applyFilters(
237 'ghostkit.editor.grid.background',
238 '',
239 props
240 );
241
242 if (background) {
243 className = classnames(className, 'ghostkit-grid-with-bg');
244 }
245
246 className = applyFilters('ghostkit.editor.className', className, props);
247
248 const blockProps = useBlockProps({
249 className,
250 });
251
252 const { children, ...innerBlocksProps } = useInnerBlocksProps(blockProps, {
253 allowedBlocks: ['ghostkit/grid-column'],
254 orientation: 'horizontal',
255 renderAppender: false,
256 });
257
258 return (
259 <div {...innerBlocksProps}>
260 {columnsCount > 0 ? (
261 <BlockControls>
262 <ToolbarGroup>
263 <ToolbarButton
264 icon={getIcon('icon-vertical-top')}
265 title={__('Content Vertical Start', 'ghostkit')}
266 onClick={() => setAttributes({ verticalAlign: '' })}
267 isActive={verticalAlign === ''}
268 />
269 <ToolbarButton
270 icon={getIcon('icon-vertical-center')}
271 title={__('Content Vertical Center', 'ghostkit')}
272 onClick={() =>
273 setAttributes({ verticalAlign: 'center' })
274 }
275 isActive={verticalAlign === 'center'}
276 />
277 <ToolbarButton
278 icon={getIcon('icon-vertical-bottom')}
279 title={__('Content Vertical End', 'ghostkit')}
280 onClick={() =>
281 setAttributes({ verticalAlign: 'end' })
282 }
283 isActive={verticalAlign === 'end'}
284 />
285 </ToolbarGroup>
286 </BlockControls>
287 ) : null}
288 <InspectorControls>
289 <ApplyFilters
290 name="ghostkit.editor.controls"
291 attribute="columns"
292 props={props}
293 >
294 <PanelBody>
295 <RangeControl
296 label={__('Columns', 'ghostkit')}
297 value={columnsCount}
298 onChange={(value) => updateColumns(value)}
299 min={1}
300 max={12}
301 allowCustomMax
302 __next40pxDefaultSize
303 __nextHasNoMarginBottom
304 />
305 </PanelBody>
306 </ApplyFilters>
307 </InspectorControls>
308 {columnsCount > 0 ? (
309 <InspectorControls>
310 <PanelBody>
311 <ToggleGroup
312 label={__('Vertical alignment', 'ghostkit')}
313 value={verticalAlign}
314 options={[
315 {
316 icon: getIcon('icon-vertical-top'),
317 label: __('Top', 'ghostkit'),
318 value: '',
319 },
320 {
321 icon: getIcon('icon-vertical-center'),
322 label: __('Center', 'ghostkit'),
323 value: 'center',
324 },
325 {
326 icon: getIcon('icon-vertical-bottom'),
327 label: __('Bottom', 'ghostkit'),
328 value: 'end',
329 },
330 ]}
331 onChange={(value) => {
332 setAttributes({ verticalAlign: value });
333 }}
334 isDeselectable
335 isAdaptiveWidth
336 />
337 <ToggleGroup
338 label={__('Horizontal alignment', 'ghostkit')}
339 value={horizontalAlign}
340 options={[
341 {
342 icon: getIcon('icon-horizontal-start'),
343 label: __('Start', 'ghostkit'),
344 value: '',
345 },
346 {
347 icon: getIcon('icon-horizontal-center'),
348 label: __('Center', 'ghostkit'),
349 value: 'center',
350 },
351 {
352 icon: getIcon('icon-horizontal-end'),
353 label: __('End', 'ghostkit'),
354 value: 'end',
355 },
356 {
357 icon: getIcon('icon-horizontal-around'),
358 label: __('Around', 'ghostkit'),
359 value: 'around',
360 },
361 {
362 icon: getIcon('icon-horizontal-between'),
363 label: __('Space Between', 'ghostkit'),
364 value: 'between',
365 },
366 ]}
367 onChange={(value) => {
368 setAttributes({ horizontalAlign: value });
369 }}
370 isDeselectable
371 />
372 </PanelBody>
373 <PanelBody>
374 <GapSettings
375 gap={gap}
376 gapCustom={gapCustom}
377 gapVerticalCustom={gapVerticalCustom}
378 onChange={(data) => {
379 setAttributes(data);
380 }}
381 allowVerticalGap
382 />
383 </PanelBody>
384 </InspectorControls>
385 ) : null}
386 <InspectorControls>
387 <div className="ghostkit-background-controls">
388 <ApplyFilters
389 name="ghostkit.editor.controls"
390 attribute="background"
391 props={props}
392 />
393 </div>
394 </InspectorControls>
395 {columnsCount > 0 ? (
396 <>
397 {background}
398 <div className="ghostkit-grid-inner">{children}</div>
399 </>
400 ) : (
401 <LayoutsSelector />
402 )}
403 </div>
404 );
405 }
406