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

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