PluginProbe
Block Animations, Motion & Scroll Effects – Ghost Kit / 3.3.3
Block Animations, Motion & Scroll Effects – Ghost Kit v3.3.3
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.3.3, at gutenberg/blocks/grid/edit.js

404 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 />
303 </PanelBody>
304 </ApplyFilters>
305 </InspectorControls>
306 {columnsCount > 0 ? (
307 <InspectorControls>
308 <PanelBody>
309 <ToggleGroup
310 label={__('Vertical alignment', 'ghostkit')}
311 value={verticalAlign}
312 options={[
313 {
314 icon: getIcon('icon-vertical-top'),
315 label: __('Top', 'ghostkit'),
316 value: '',
317 },
318 {
319 icon: getIcon('icon-vertical-center'),
320 label: __('Center', 'ghostkit'),
321 value: 'center',
322 },
323 {
324 icon: getIcon('icon-vertical-bottom'),
325 label: __('Bottom', 'ghostkit'),
326 value: 'end',
327 },
328 ]}
329 onChange={(value) => {
330 setAttributes({ verticalAlign: value });
331 }}
332 isDeselectable
333 isAdaptiveWidth
334 />
335 <ToggleGroup
336 label={__('Horizontal alignment', 'ghostkit')}
337 value={horizontalAlign}
338 options={[
339 {
340 icon: getIcon('icon-horizontal-start'),
341 label: __('Start', 'ghostkit'),
342 value: '',
343 },
344 {
345 icon: getIcon('icon-horizontal-center'),
346 label: __('Center', 'ghostkit'),
347 value: 'center',
348 },
349 {
350 icon: getIcon('icon-horizontal-end'),
351 label: __('End', 'ghostkit'),
352 value: 'end',
353 },
354 {
355 icon: getIcon('icon-horizontal-around'),
356 label: __('Around', 'ghostkit'),
357 value: 'around',
358 },
359 {
360 icon: getIcon('icon-horizontal-between'),
361 label: __('Space Between', 'ghostkit'),
362 value: 'between',
363 },
364 ]}
365 onChange={(value) => {
366 setAttributes({ horizontalAlign: value });
367 }}
368 isDeselectable
369 />
370 </PanelBody>
371 <PanelBody>
372 <GapSettings
373 gap={gap}
374 gapCustom={gapCustom}
375 gapVerticalCustom={gapVerticalCustom}
376 onChange={(data) => {
377 setAttributes(data);
378 }}
379 allowVerticalGap
380 />
381 </PanelBody>
382 </InspectorControls>
383 ) : null}
384 <InspectorControls>
385 <div className="ghostkit-background-controls">
386 <ApplyFilters
387 name="ghostkit.editor.controls"
388 attribute="background"
389 props={props}
390 />
391 </div>
392 </InspectorControls>
393 {columnsCount > 0 ? (
394 <>
395 {background}
396 <div className="ghostkit-grid-inner">{children}</div>
397 </>
398 ) : (
399 <LayoutsSelector />
400 )}
401 </div>
402 );
403 }
404