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

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