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 / form / edit.js

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

327 lines 7.3 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 import { throttle } from 'throttle-debounce';
3
4 import {
5 InnerBlocks,
6 InspectorControls,
7 useBlockProps,
8 useInnerBlocksProps,
9 } from '@wordpress/block-editor';
10 import {
11 BaseControl,
12 PanelBody,
13 TextareaControl,
14 TextControl,
15 ToggleControl,
16 } from '@wordpress/components';
17 import { useDispatch, useSelect } from '@wordpress/data';
18 import { useEffect } from '@wordpress/element';
19 import { applyFilters } from '@wordpress/hooks';
20 import { __ } from '@wordpress/i18n';
21
22 import ToggleGroup from '../../components/toggle-group';
23 import RecaptchaSettings from './recaptcha';
24
25 const TEMPLATE = [
26 ['ghostkit/form-field-name', { slug: 'field_name' }],
27 ['ghostkit/form-field-email', { slug: 'field_email', required: true }],
28 [
29 'ghostkit/form-field-text',
30 {
31 slug: 'field_subject',
32 label: __('Subject', 'ghostkit'),
33 required: true,
34 },
35 ],
36 [
37 'ghostkit/form-field-textarea',
38 {
39 slug: 'field_message',
40 label: __('Message', 'ghostkit'),
41 required: true,
42 },
43 ],
44 ['ghostkit/form-submit-button'],
45 ];
46 const ALLOWED_BLOCKS = [
47 'core/paragraph',
48 'core/heading',
49 'core/list',
50 'core/divider',
51 'core/columns',
52 'ghostkit/divider',
53 'ghostkit/grid',
54 ];
55
56 /**
57 * Parse all Form inner blocks and get Fields data.
58 *
59 * @param {Object} formData Form block data.
60 *
61 * @return {Array} - fields list.
62 */
63 function getAllFieldsData(formData) {
64 let result = [];
65
66 if (formData.innerBlocks && formData.innerBlocks.length) {
67 formData.innerBlocks.forEach((block) => {
68 // field data.
69 if (block.name && /^ghostkit\/form-field/g.test(block.name)) {
70 result.push({
71 clientId: block.clientId,
72 name: block.name,
73 type: block.name.replace(/^ghostkit\/form-field-/g, ''),
74 attributes: block.attributes,
75 });
76 }
77
78 // inner blocks.
79 if (block.innerBlocks && block.innerBlocks.length) {
80 result = [...result, ...getAllFieldsData(block)];
81 }
82 });
83 }
84
85 return result;
86 }
87
88 /**
89 * Get unique field slug.
90 *
91 * @param {Object} data - field data.
92 * @param {Object} uniqueIds - all available uniqu IDs.
93 *
94 * @return {string} - unique slug.
95 */
96 function getUniqueFieldSlug(data, uniqueIds) {
97 let newSlug = `field_${data.type}`;
98
99 // check if slug already exist.
100 let tryCount = 100;
101 let i = 0;
102 while (
103 typeof uniqueIds[data.type][newSlug] !== 'undefined' &&
104 tryCount > 0
105 ) {
106 i += 1;
107 tryCount -= 1;
108 newSlug = `field_${data.type}_${i}`;
109 }
110
111 return newSlug;
112 }
113
114 /**
115 * Block Edit component.
116 *
117 * @param props
118 */
119 export default function BlockEdit(props) {
120 const { attributes, setAttributes, clientId } = props;
121
122 let { className = '' } = props;
123
124 const {
125 mailAllow,
126 mailTo,
127 mailSubject,
128 mailFrom,
129 mailReplyTo,
130 mailMessage,
131
132 confirmationType,
133 confirmationMessage,
134 confirmationRedirect,
135 } = attributes;
136
137 const { isSelectedBlockInRoot, allFieldsData } = useSelect(
138 (select) => {
139 const { getBlock, isBlockSelected, hasSelectedInnerBlock } =
140 select('core/block-editor');
141
142 return {
143 allFieldsData: getAllFieldsData(getBlock(clientId)),
144 isSelectedBlockInRoot:
145 isBlockSelected(clientId) ||
146 hasSelectedInnerBlock(clientId, true),
147 };
148 },
149 [clientId]
150 );
151
152 const { updateBlockAttributes } = useDispatch('core/block-editor');
153
154 function updateFieldsSlugs() {
155 const uniqueIds = {};
156
157 // Collect all available slugs.
158 allFieldsData.forEach((data) => {
159 if (!uniqueIds[data.type]) {
160 uniqueIds[data.type] = {};
161 }
162 if (data.attributes.slug) {
163 // Slug already exist.
164 if (
165 typeof uniqueIds[data.type][data.attributes.slug] !==
166 'undefined'
167 ) {
168 const newSlug = getUniqueFieldSlug(data, uniqueIds);
169
170 uniqueIds[data.type][newSlug] = true;
171
172 updateBlockAttributes(data.clientId, {
173 slug: newSlug,
174 });
175 } else {
176 uniqueIds[data.type][data.attributes.slug] = true;
177 }
178 }
179 });
180
181 // Generate slugs for new fields.
182 allFieldsData.forEach((data) => {
183 if (!uniqueIds[data.type]) {
184 uniqueIds[data.type] = {};
185 }
186
187 if (!data.attributes.slug) {
188 const newSlug = getUniqueFieldSlug(data, uniqueIds);
189
190 uniqueIds[data.type][newSlug] = true;
191
192 updateBlockAttributes(data.clientId, {
193 slug: newSlug,
194 });
195 }
196 });
197 }
198
199 const maybeUpdateFieldSlug = throttle(200, () => {
200 updateFieldsSlugs();
201 });
202
203 // Mount and update.
204 useEffect(() => {
205 maybeUpdateFieldSlug();
206 });
207
208 className = classnames(className, 'ghostkit-form');
209 className = applyFilters('ghostkit.editor.className', className, props);
210
211 const blockProps = useBlockProps({ className });
212 const { children, ...innerBlockProps } = useInnerBlocksProps(blockProps, {
213 template: TEMPLATE,
214 allowedBlocks: ALLOWED_BLOCKS,
215 renderAppender: () => null,
216 });
217
218 return (
219 <>
220 <InspectorControls>
221 <PanelBody title={__('Mail', 'ghostkit')}>
222 {mailAllow ? (
223 <>
224 <TextControl
225 label={__('Send To Email Address', 'ghostkit')}
226 value={mailTo}
227 onChange={(val) =>
228 setAttributes({ mailTo: val })
229 }
230 />
231 <TextControl
232 label={__('Subject', 'ghostkit')}
233 value={mailSubject}
234 onChange={(val) =>
235 setAttributes({ mailSubject: val })
236 }
237 />
238 <TextControl
239 label={__('From', 'ghostkit')}
240 value={mailFrom}
241 onChange={(val) =>
242 setAttributes({ mailFrom: val })
243 }
244 />
245 <TextControl
246 label={__('Reply To', 'ghostkit')}
247 value={mailReplyTo}
248 onChange={(val) =>
249 setAttributes({ mailReplyTo: val })
250 }
251 />
252 <TextareaControl
253 label={__('Message', 'ghostkit')}
254 value={mailMessage}
255 onChange={(val) =>
256 setAttributes({ mailMessage: val })
257 }
258 />
259 </>
260 ) : null}
261 <BaseControl
262 id={__('Send Email', 'ghostkit')}
263 label={__('Send Email', 'ghostkit')}
264 help={__(
265 "In case if you don't want to receive email messages from this form, you may disable sending emails functionality."
266 )}
267 >
268 <ToggleControl
269 Label={__('Yes', 'ghostkit')}
270 checked={!!mailAllow}
271 onChange={() =>
272 setAttributes({ mailAllow: !mailAllow })
273 }
274 />
275 </BaseControl>
276 </PanelBody>
277 <PanelBody title={__('Confirmation', 'ghostkit')}>
278 <ToggleGroup
279 label={__('Type', 'ghostkit')}
280 value={confirmationType}
281 options={[
282 {
283 label: __('Message', 'ghostkit'),
284 value: 'message',
285 },
286 {
287 label: __('Redirect', 'ghostkit'),
288 value: 'redirect',
289 },
290 ]}
291 onChange={(value) => {
292 setAttributes({ confirmationType: value });
293 }}
294 isDeselectable
295 />
296
297 {!confirmationType || confirmationType === 'message' ? (
298 <TextareaControl
299 label={__('Message', 'ghostkit')}
300 value={confirmationMessage}
301 onChange={(val) =>
302 setAttributes({ confirmationMessage: val })
303 }
304 />
305 ) : null}
306 {confirmationType === 'redirect' ? (
307 <TextControl
308 label={__('Redirect URL', 'ghostkit')}
309 value={confirmationRedirect}
310 onChange={(val) =>
311 setAttributes({ confirmationRedirect: val })
312 }
313 />
314 ) : null}
315 </PanelBody>
316 <RecaptchaSettings />
317 </InspectorControls>
318 <div {...innerBlockProps}>
319 {children}
320 {isSelectedBlockInRoot ? (
321 <InnerBlocks.ButtonBlockAppender />
322 ) : null}
323 </div>
324 </>
325 );
326 }
327