PluginProbe
Gutenberg / 17.6.2
Gutenberg v17.6.2
24.0.0 23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 12.6.0 All 403 releases
gutenberg / build / patterns / index.js

index.js in Gutenberg 17.6.2, at build/patterns/index.js

1,287 lines 43.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /******/ (() => { // webpackBootstrap
2 /******/ "use strict";
3 /******/ // The require scope
4 /******/ var __webpack_require__ = {};
5 /******/
6 /************************************************************************/
7 /******/ /* webpack/runtime/define property getters */
8 /******/ (() => {
9 /******/ // define getter functions for harmony exports
10 /******/ __webpack_require__.d = (exports, definition) => {
11 /******/ for(var key in definition) {
12 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
13 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
14 /******/ }
15 /******/ }
16 /******/ };
17 /******/ })();
18 /******/
19 /******/ /* webpack/runtime/hasOwnProperty shorthand */
20 /******/ (() => {
21 /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
22 /******/ })();
23 /******/
24 /******/ /* webpack/runtime/make namespace object */
25 /******/ (() => {
26 /******/ // define __esModule on exports
27 /******/ __webpack_require__.r = (exports) => {
28 /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
29 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
30 /******/ }
31 /******/ Object.defineProperty(exports, '__esModule', { value: true });
32 /******/ };
33 /******/ })();
34 /******/
35 /************************************************************************/
36 var __webpack_exports__ = {};
37 // ESM COMPAT FLAG
38 __webpack_require__.r(__webpack_exports__);
39
40 // EXPORTS
41 __webpack_require__.d(__webpack_exports__, {
42 privateApis: () => (/* reexport */ privateApis),
43 store: () => (/* reexport */ store)
44 });
45
46 // NAMESPACE OBJECT: ./packages/patterns/build-module/store/actions.js
47 var actions_namespaceObject = {};
48 __webpack_require__.r(actions_namespaceObject);
49 __webpack_require__.d(actions_namespaceObject, {
50 convertSyncedPatternToStatic: () => (convertSyncedPatternToStatic),
51 createPattern: () => (createPattern),
52 createPatternFromFile: () => (createPatternFromFile),
53 setEditingPattern: () => (setEditingPattern)
54 });
55
56 // NAMESPACE OBJECT: ./packages/patterns/build-module/store/selectors.js
57 var selectors_namespaceObject = {};
58 __webpack_require__.r(selectors_namespaceObject);
59 __webpack_require__.d(selectors_namespaceObject, {
60 isEditingPattern: () => (selectors_isEditingPattern)
61 });
62
63 ;// CONCATENATED MODULE: external ["wp","data"]
64 const external_wp_data_namespaceObject = window["wp"]["data"];
65 ;// CONCATENATED MODULE: ./packages/patterns/build-module/store/reducer.js
66 /**
67 * WordPress dependencies
68 */
69
70 function isEditingPattern(state = {}, action) {
71 if (action?.type === 'SET_EDITING_PATTERN') {
72 return {
73 ...state,
74 [action.clientId]: action.isEditing
75 };
76 }
77 return state;
78 }
79 /* harmony default export */ const reducer = ((0,external_wp_data_namespaceObject.combineReducers)({
80 isEditingPattern
81 }));
82
83 ;// CONCATENATED MODULE: external ["wp","blocks"]
84 const external_wp_blocks_namespaceObject = window["wp"]["blocks"];
85 ;// CONCATENATED MODULE: external ["wp","coreData"]
86 const external_wp_coreData_namespaceObject = window["wp"]["coreData"];
87 ;// CONCATENATED MODULE: external ["wp","blockEditor"]
88 const external_wp_blockEditor_namespaceObject = window["wp"]["blockEditor"];
89 ;// CONCATENATED MODULE: external ["wp","i18n"]
90 const external_wp_i18n_namespaceObject = window["wp"]["i18n"];
91 ;// CONCATENATED MODULE: ./packages/patterns/build-module/constants.js
92 /**
93 * WordPress dependencies
94 */
95
96 const PATTERN_TYPES = {
97 theme: 'pattern',
98 user: 'wp_block'
99 };
100 const PATTERN_DEFAULT_CATEGORY = 'all-patterns';
101 const PATTERN_USER_CATEGORY = 'my-patterns';
102 const EXCLUDED_PATTERN_SOURCES = ['core', 'pattern-directory/core', 'pattern-directory/featured'];
103 const PATTERN_SYNC_TYPES = {
104 full: 'fully',
105 unsynced: 'unsynced'
106 };
107
108 // TODO: This should not be hardcoded. Maybe there should be a config and/or an UI.
109 const PARTIAL_SYNCING_SUPPORTED_BLOCKS = {
110 'core/paragraph': {
111 content: (0,external_wp_i18n_namespaceObject.__)('Content')
112 },
113 'core/heading': {
114 content: (0,external_wp_i18n_namespaceObject.__)('Content')
115 },
116 'core/button': {
117 text: (0,external_wp_i18n_namespaceObject.__)('Text'),
118 url: (0,external_wp_i18n_namespaceObject.__)('URL')
119 },
120 'core/image': {
121 url: (0,external_wp_i18n_namespaceObject.__)('URL'),
122 title: (0,external_wp_i18n_namespaceObject.__)('Title'),
123 alt: (0,external_wp_i18n_namespaceObject.__)('Alt Text')
124 }
125 };
126
127 ;// CONCATENATED MODULE: ./packages/patterns/build-module/store/actions.js
128 /**
129 * WordPress dependencies
130 */
131
132
133
134
135
136 /**
137 * Internal dependencies
138 */
139
140
141 /**
142 * Returns a generator converting one or more static blocks into a pattern, or creating a new empty pattern.
143 *
144 * @param {string} title Pattern title.
145 * @param {'full'|'unsynced'} syncType They way block is synced, 'full' or 'unsynced'.
146 * @param {string|undefined} [content] Optional serialized content of blocks to convert to pattern.
147 * @param {number[]|undefined} [categories] Ids of any selected categories.
148 */
149 const createPattern = (title, syncType, content, categories) => async ({
150 registry
151 }) => {
152 const meta = syncType === PATTERN_SYNC_TYPES.unsynced ? {
153 wp_pattern_sync_status: syncType
154 } : undefined;
155 const reusableBlock = {
156 title,
157 content,
158 status: 'publish',
159 meta,
160 wp_pattern_category: categories
161 };
162 const updatedRecord = await registry.dispatch(external_wp_coreData_namespaceObject.store).saveEntityRecord('postType', 'wp_block', reusableBlock);
163 return updatedRecord;
164 };
165
166 /**
167 * Create a pattern from a JSON file.
168 * @param {File} file The JSON file instance of the pattern.
169 * @param {number[]|undefined} [categories] Ids of any selected categories.
170 */
171 const createPatternFromFile = (file, categories) => async ({
172 dispatch
173 }) => {
174 const fileContent = await file.text();
175 /** @type {import('./types').PatternJSON} */
176 let parsedContent;
177 try {
178 parsedContent = JSON.parse(fileContent);
179 } catch (e) {
180 throw new Error('Invalid JSON file');
181 }
182 if (parsedContent.__file !== 'wp_block' || !parsedContent.title || !parsedContent.content || typeof parsedContent.title !== 'string' || typeof parsedContent.content !== 'string' || parsedContent.syncStatus && typeof parsedContent.syncStatus !== 'string') {
183 throw new Error('Invalid pattern JSON file');
184 }
185 const pattern = await dispatch.createPattern(parsedContent.title, parsedContent.syncStatus, parsedContent.content, categories);
186 return pattern;
187 };
188
189 /**
190 * Returns a generator converting a synced pattern block into a static block.
191 *
192 * @param {string} clientId The client ID of the block to attach.
193 */
194 const convertSyncedPatternToStatic = clientId => ({
195 registry
196 }) => {
197 const patternBlock = registry.select(external_wp_blockEditor_namespaceObject.store).getBlock(clientId);
198 function cloneBlocksAndRemoveBindings(blocks) {
199 return blocks.map(block => {
200 let metadata = block.attributes.metadata;
201 if (metadata) {
202 metadata = {
203 ...metadata
204 };
205 delete metadata.id;
206 delete metadata.bindings;
207 }
208 return (0,external_wp_blocks_namespaceObject.cloneBlock)(block, {
209 metadata: metadata && Object.keys(metadata).length > 0 ? metadata : undefined
210 }, cloneBlocksAndRemoveBindings(block.innerBlocks));
211 });
212 }
213 registry.dispatch(external_wp_blockEditor_namespaceObject.store).replaceBlocks(patternBlock.clientId, cloneBlocksAndRemoveBindings(patternBlock.innerBlocks));
214 };
215
216 /**
217 * Returns an action descriptor for SET_EDITING_PATTERN action.
218 *
219 * @param {string} clientId The clientID of the pattern to target.
220 * @param {boolean} isEditing Whether the block should be in editing state.
221 * @return {Object} Action descriptor.
222 */
223 function setEditingPattern(clientId, isEditing) {
224 return {
225 type: 'SET_EDITING_PATTERN',
226 clientId,
227 isEditing
228 };
229 }
230
231 ;// CONCATENATED MODULE: ./packages/patterns/build-module/store/constants.js
232 /**
233 * Module Constants
234 */
235 const STORE_NAME = 'core/patterns';
236
237 ;// CONCATENATED MODULE: ./packages/patterns/build-module/store/selectors.js
238 /**
239 * Returns true if pattern is in the editing state.
240 *
241 * @param {Object} state Global application state.
242 * @param {number} clientId the clientID of the block.
243 * @return {boolean} Whether the pattern is in the editing state.
244 */
245 function selectors_isEditingPattern(state, clientId) {
246 return state.isEditingPattern[clientId];
247 }
248
249 ;// CONCATENATED MODULE: external ["wp","privateApis"]
250 const external_wp_privateApis_namespaceObject = window["wp"]["privateApis"];
251 ;// CONCATENATED MODULE: ./packages/patterns/build-module/lock-unlock.js
252 /**
253 * WordPress dependencies
254 */
255
256 const {
257 lock,
258 unlock
259 } = (0,external_wp_privateApis_namespaceObject.__dangerousOptInToUnstableAPIsOnlyForCoreModules)('I know using unstable features means my theme or plugin will inevitably break in the next version of WordPress.', '@wordpress/patterns');
260
261 ;// CONCATENATED MODULE: ./packages/patterns/build-module/store/index.js
262 /**
263 * WordPress dependencies
264 */
265
266
267 /**
268 * Internal dependencies
269 */
270
271
272
273
274
275
276 /**
277 * Post editor data store configuration.
278 *
279 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/data/README.md#registerStore
280 *
281 * @type {Object}
282 */
283 const storeConfig = {
284 reducer: reducer
285 };
286
287 /**
288 * Store definition for the editor namespace.
289 *
290 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/data/README.md#createReduxStore
291 *
292 * @type {Object}
293 */
294 const store = (0,external_wp_data_namespaceObject.createReduxStore)(STORE_NAME, {
295 ...storeConfig
296 });
297 (0,external_wp_data_namespaceObject.register)(store);
298 unlock(store).registerPrivateActions(actions_namespaceObject);
299 unlock(store).registerPrivateSelectors(selectors_namespaceObject);
300
301 ;// CONCATENATED MODULE: external "React"
302 const external_React_namespaceObject = window["React"];
303 ;// CONCATENATED MODULE: external ["wp","components"]
304 const external_wp_components_namespaceObject = window["wp"]["components"];
305 ;// CONCATENATED MODULE: external ["wp","element"]
306 const external_wp_element_namespaceObject = window["wp"]["element"];
307 ;// CONCATENATED MODULE: external ["wp","notices"]
308 const external_wp_notices_namespaceObject = window["wp"]["notices"];
309 ;// CONCATENATED MODULE: external ["wp","compose"]
310 const external_wp_compose_namespaceObject = window["wp"]["compose"];
311 ;// CONCATENATED MODULE: external ["wp","htmlEntities"]
312 const external_wp_htmlEntities_namespaceObject = window["wp"]["htmlEntities"];
313 ;// CONCATENATED MODULE: ./packages/patterns/build-module/components/category-selector.js
314
315 /**
316 * WordPress dependencies
317 */
318
319
320
321
322
323 const unescapeString = arg => {
324 return (0,external_wp_htmlEntities_namespaceObject.decodeEntities)(arg);
325 };
326 const CATEGORY_SLUG = 'wp_pattern_category';
327 function CategorySelector({
328 categoryTerms,
329 onChange,
330 categoryMap
331 }) {
332 const [search, setSearch] = (0,external_wp_element_namespaceObject.useState)('');
333 const debouncedSearch = (0,external_wp_compose_namespaceObject.useDebounce)(setSearch, 500);
334 const suggestions = (0,external_wp_element_namespaceObject.useMemo)(() => {
335 return Array.from(categoryMap.values()).map(category => unescapeString(category.label)).filter(category => {
336 if (search !== '') {
337 return category.toLowerCase().includes(search.toLowerCase());
338 }
339 return true;
340 }).sort((a, b) => a.localeCompare(b));
341 }, [search, categoryMap]);
342 function handleChange(termNames) {
343 const uniqueTerms = termNames.reduce((terms, newTerm) => {
344 if (!terms.some(term => term.toLowerCase() === newTerm.toLowerCase())) {
345 terms.push(newTerm);
346 }
347 return terms;
348 }, []);
349 onChange(uniqueTerms);
350 }
351 return (0,external_React_namespaceObject.createElement)(external_wp_components_namespaceObject.FormTokenField, {
352 className: "patterns-menu-items__convert-modal-categories",
353 value: categoryTerms,
354 suggestions: suggestions,
355 onChange: handleChange,
356 onInputChange: debouncedSearch,
357 label: (0,external_wp_i18n_namespaceObject.__)('Categories'),
358 tokenizeOnBlur: true,
359 __experimentalExpandOnFocus: true,
360 __next40pxDefaultSize: true,
361 __nextHasNoMarginBottom: true
362 });
363 }
364
365 ;// CONCATENATED MODULE: ./packages/patterns/build-module/components/create-pattern-modal.js
366
367 /**
368 * WordPress dependencies
369 */
370
371
372
373
374
375
376
377 /**
378 * Internal dependencies
379 */
380
381
382 /**
383 * Internal dependencies
384 */
385
386
387
388 function CreatePatternModal({
389 className = 'patterns-menu-items__convert-modal',
390 modalTitle = (0,external_wp_i18n_namespaceObject.__)('Create pattern'),
391 ...restProps
392 }) {
393 return (0,external_React_namespaceObject.createElement)(external_wp_components_namespaceObject.Modal, {
394 title: modalTitle,
395 onRequestClose: restProps.onClose,
396 overlayClassName: className
397 }, (0,external_React_namespaceObject.createElement)(CreatePatternModalContents, {
398 ...restProps
399 }));
400 }
401 function CreatePatternModalContents({
402 confirmLabel = (0,external_wp_i18n_namespaceObject.__)('Create'),
403 defaultCategories = [],
404 content,
405 onClose,
406 onError,
407 onSuccess,
408 defaultSyncType = PATTERN_SYNC_TYPES.full,
409 defaultTitle = ''
410 }) {
411 const [syncType, setSyncType] = (0,external_wp_element_namespaceObject.useState)(defaultSyncType);
412 const [categoryTerms, setCategoryTerms] = (0,external_wp_element_namespaceObject.useState)(defaultCategories);
413 const [title, setTitle] = (0,external_wp_element_namespaceObject.useState)(defaultTitle);
414 const [isSaving, setIsSaving] = (0,external_wp_element_namespaceObject.useState)(false);
415 const {
416 createPattern
417 } = unlock((0,external_wp_data_namespaceObject.useDispatch)(store));
418 const {
419 saveEntityRecord,
420 invalidateResolution
421 } = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_coreData_namespaceObject.store);
422 const {
423 createErrorNotice
424 } = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_notices_namespaceObject.store);
425 const {
426 corePatternCategories,
427 userPatternCategories
428 } = (0,external_wp_data_namespaceObject.useSelect)(select => {
429 const {
430 getUserPatternCategories,
431 getBlockPatternCategories
432 } = select(external_wp_coreData_namespaceObject.store);
433 return {
434 corePatternCategories: getBlockPatternCategories(),
435 userPatternCategories: getUserPatternCategories()
436 };
437 });
438 const categoryMap = (0,external_wp_element_namespaceObject.useMemo)(() => {
439 // Merge the user and core pattern categories and remove any duplicates.
440 const uniqueCategories = new Map();
441 userPatternCategories.forEach(category => {
442 uniqueCategories.set(category.label.toLowerCase(), {
443 label: category.label,
444 name: category.name,
445 id: category.id
446 });
447 });
448 corePatternCategories.forEach(category => {
449 if (!uniqueCategories.has(category.label.toLowerCase()) &&
450 // There are two core categories with `Post` label so explicitly remove the one with
451 // the `query` slug to avoid any confusion.
452 category.name !== 'query') {
453 uniqueCategories.set(category.label.toLowerCase(), {
454 label: category.label,
455 name: category.name
456 });
457 }
458 });
459 return uniqueCategories;
460 }, [userPatternCategories, corePatternCategories]);
461 async function onCreate(patternTitle, sync) {
462 if (!title || isSaving) {
463 return;
464 }
465 try {
466 setIsSaving(true);
467 const categories = await Promise.all(categoryTerms.map(termName => findOrCreateTerm(termName)));
468 const newPattern = await createPattern(patternTitle, sync, typeof content === 'function' ? content() : content, categories);
469 onSuccess({
470 pattern: newPattern,
471 categoryId: PATTERN_DEFAULT_CATEGORY
472 });
473 } catch (error) {
474 createErrorNotice(error.message, {
475 type: 'snackbar',
476 id: 'pattern-create'
477 });
478 onError?.();
479 } finally {
480 setIsSaving(false);
481 setCategoryTerms([]);
482 setTitle('');
483 }
484 }
485
486 /**
487 * @param {string} term
488 * @return {Promise<number>} The pattern category id.
489 */
490 async function findOrCreateTerm(term) {
491 try {
492 const existingTerm = categoryMap.get(term.toLowerCase());
493 if (existingTerm && existingTerm.id) {
494 return existingTerm.id;
495 }
496 // If we have an existing core category we need to match the new user category to the
497 // correct slug rather than autogenerating it to prevent duplicates, eg. the core `Headers`
498 // category uses the singular `header` as the slug.
499 const termData = existingTerm ? {
500 name: existingTerm.label,
501 slug: existingTerm.name
502 } : {
503 name: term
504 };
505 const newTerm = await saveEntityRecord('taxonomy', CATEGORY_SLUG, termData, {
506 throwOnError: true
507 });
508 invalidateResolution('getUserPatternCategories');
509 return newTerm.id;
510 } catch (error) {
511 if (error.code !== 'term_exists') {
512 throw error;
513 }
514 return error.data.term_id;
515 }
516 }
517 return (0,external_React_namespaceObject.createElement)("form", {
518 onSubmit: event => {
519 event.preventDefault();
520 onCreate(title, syncType);
521 }
522 }, (0,external_React_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalVStack, {
523 spacing: "5"
524 }, (0,external_React_namespaceObject.createElement)(external_wp_components_namespaceObject.TextControl, {
525 label: (0,external_wp_i18n_namespaceObject.__)('Name'),
526 value: title,
527 onChange: setTitle,
528 placeholder: (0,external_wp_i18n_namespaceObject.__)('My pattern'),
529 className: "patterns-create-modal__name-input",
530 __nextHasNoMarginBottom: true,
531 __next40pxDefaultSize: true
532 }), (0,external_React_namespaceObject.createElement)(CategorySelector, {
533 categoryTerms: categoryTerms,
534 onChange: setCategoryTerms,
535 categoryMap: categoryMap
536 }), (0,external_React_namespaceObject.createElement)(external_wp_components_namespaceObject.ToggleControl, {
537 label: (0,external_wp_i18n_namespaceObject._x)('Synced', 'Option that makes an individual pattern synchronized'),
538 help: (0,external_wp_i18n_namespaceObject.__)('Sync this pattern across multiple locations.'),
539 checked: syncType === PATTERN_SYNC_TYPES.full,
540 onChange: () => {
541 setSyncType(syncType === PATTERN_SYNC_TYPES.full ? PATTERN_SYNC_TYPES.unsynced : PATTERN_SYNC_TYPES.full);
542 }
543 }), (0,external_React_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalHStack, {
544 justify: "right"
545 }, (0,external_React_namespaceObject.createElement)(external_wp_components_namespaceObject.Button, {
546 __next40pxDefaultSize: true,
547 variant: "tertiary",
548 onClick: () => {
549 onClose();
550 setTitle('');
551 }
552 }, (0,external_wp_i18n_namespaceObject.__)('Cancel')), (0,external_React_namespaceObject.createElement)(external_wp_components_namespaceObject.Button, {
553 __next40pxDefaultSize: true,
554 variant: "primary",
555 type: "submit",
556 "aria-disabled": !title || isSaving,
557 isBusy: isSaving
558 }, confirmLabel))));
559 }
560
561 ;// CONCATENATED MODULE: ./packages/patterns/build-module/components/duplicate-pattern-modal.js
562
563 /**
564 * WordPress dependencies
565 */
566
567
568
569
570
571 /**
572 * Internal dependencies
573 */
574
575
576 function getTermLabels(pattern, categories) {
577 // Theme patterns rely on core pattern categories.
578 if (pattern.type !== PATTERN_TYPES.user) {
579 return categories.core?.filter(category => pattern.categories.includes(category.name)).map(category => category.label);
580 }
581 return categories.user?.filter(category => pattern.wp_pattern_category.includes(category.id)).map(category => category.label);
582 }
583 function useDuplicatePatternProps({
584 pattern,
585 onSuccess
586 }) {
587 const {
588 createSuccessNotice
589 } = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_notices_namespaceObject.store);
590 const categories = (0,external_wp_data_namespaceObject.useSelect)(select => {
591 const {
592 getUserPatternCategories,
593 getBlockPatternCategories
594 } = select(external_wp_coreData_namespaceObject.store);
595 return {
596 core: getBlockPatternCategories(),
597 user: getUserPatternCategories()
598 };
599 });
600 if (!pattern) {
601 return null;
602 }
603 return {
604 content: pattern.content,
605 defaultCategories: getTermLabels(pattern, categories),
606 defaultSyncType: pattern.type !== PATTERN_TYPES.user // Theme patterns are unsynced by default.
607 ? PATTERN_SYNC_TYPES.unsynced : pattern.wp_pattern_sync_status || PATTERN_SYNC_TYPES.full,
608 defaultTitle: (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: %s: Existing pattern title */
609 (0,external_wp_i18n_namespaceObject.__)('%s (Copy)'), typeof pattern.title === 'string' ? pattern.title : pattern.title.raw),
610 onSuccess: ({
611 pattern: newPattern
612 }) => {
613 createSuccessNotice((0,external_wp_i18n_namespaceObject.sprintf)(
614 // translators: %s: The new pattern's title e.g. 'Call to action (copy)'.
615 (0,external_wp_i18n_namespaceObject.__)('"%s" duplicated.'), newPattern.title.raw), {
616 type: 'snackbar',
617 id: 'patterns-create'
618 });
619 onSuccess?.({
620 pattern: newPattern
621 });
622 }
623 };
624 }
625 function DuplicatePatternModal({
626 pattern,
627 onClose,
628 onSuccess
629 }) {
630 const duplicatedProps = useDuplicatePatternProps({
631 pattern,
632 onSuccess
633 });
634 if (!pattern) {
635 return null;
636 }
637 return (0,external_React_namespaceObject.createElement)(CreatePatternModal, {
638 modalTitle: (0,external_wp_i18n_namespaceObject.__)('Duplicate pattern'),
639 confirmLabel: (0,external_wp_i18n_namespaceObject.__)('Duplicate'),
640 onClose: onClose,
641 onError: onClose,
642 ...duplicatedProps
643 });
644 }
645
646 ;// CONCATENATED MODULE: ./packages/patterns/build-module/components/rename-pattern-modal.js
647
648 /**
649 * WordPress dependencies
650 */
651
652
653
654
655
656
657
658 function RenamePatternModal({
659 onClose,
660 onError,
661 onSuccess,
662 pattern,
663 ...props
664 }) {
665 const originalName = (0,external_wp_htmlEntities_namespaceObject.decodeEntities)(pattern.title);
666 const [name, setName] = (0,external_wp_element_namespaceObject.useState)(originalName);
667 const [isSaving, setIsSaving] = (0,external_wp_element_namespaceObject.useState)(false);
668 const {
669 editEntityRecord,
670 __experimentalSaveSpecifiedEntityEdits: saveSpecifiedEntityEdits
671 } = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_coreData_namespaceObject.store);
672 const {
673 createSuccessNotice,
674 createErrorNotice
675 } = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_notices_namespaceObject.store);
676 const onRename = async event => {
677 event.preventDefault();
678 if (!name || name === pattern.title || isSaving) {
679 return;
680 }
681 try {
682 await editEntityRecord('postType', pattern.type, pattern.id, {
683 title: name
684 });
685 setIsSaving(true);
686 setName('');
687 onClose?.();
688 const savedRecord = await saveSpecifiedEntityEdits('postType', pattern.type, pattern.id, ['title'], {
689 throwOnError: true
690 });
691 onSuccess?.(savedRecord);
692 createSuccessNotice((0,external_wp_i18n_namespaceObject.__)('Pattern renamed'), {
693 type: 'snackbar',
694 id: 'pattern-update'
695 });
696 } catch (error) {
697 onError?.();
698 const errorMessage = error.message && error.code !== 'unknown_error' ? error.message : (0,external_wp_i18n_namespaceObject.__)('An error occurred while renaming the pattern.');
699 createErrorNotice(errorMessage, {
700 type: 'snackbar',
701 id: 'pattern-update'
702 });
703 } finally {
704 setIsSaving(false);
705 setName('');
706 }
707 };
708 const onRequestClose = () => {
709 onClose?.();
710 setName('');
711 };
712 return (0,external_React_namespaceObject.createElement)(external_wp_components_namespaceObject.Modal, {
713 title: (0,external_wp_i18n_namespaceObject.__)('Rename'),
714 ...props,
715 onRequestClose: onClose
716 }, (0,external_React_namespaceObject.createElement)("form", {
717 onSubmit: onRename
718 }, (0,external_React_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalVStack, {
719 spacing: "5"
720 }, (0,external_React_namespaceObject.createElement)(external_wp_components_namespaceObject.TextControl, {
721 __nextHasNoMarginBottom: true,
722 __next40pxDefaultSize: true,
723 label: (0,external_wp_i18n_namespaceObject.__)('Name'),
724 value: name,
725 onChange: setName,
726 required: true
727 }), (0,external_React_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalHStack, {
728 justify: "right"
729 }, (0,external_React_namespaceObject.createElement)(external_wp_components_namespaceObject.Button, {
730 __next40pxDefaultSize: true,
731 variant: "tertiary",
732 onClick: onRequestClose
733 }, (0,external_wp_i18n_namespaceObject.__)('Cancel')), (0,external_React_namespaceObject.createElement)(external_wp_components_namespaceObject.Button, {
734 __next40pxDefaultSize: true,
735 variant: "primary",
736 type: "submit"
737 }, (0,external_wp_i18n_namespaceObject.__)('Save'))))));
738 }
739
740 ;// CONCATENATED MODULE: external ["wp","primitives"]
741 const external_wp_primitives_namespaceObject = window["wp"]["primitives"];
742 ;// CONCATENATED MODULE: ./packages/icons/build-module/library/symbol.js
743
744 /**
745 * WordPress dependencies
746 */
747
748 const symbol = (0,external_React_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
749 xmlns: "http://www.w3.org/2000/svg",
750 viewBox: "0 0 24 24"
751 }, (0,external_React_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
752 d: "M21.3 10.8l-5.6-5.6c-.7-.7-1.8-.7-2.5 0l-5.6 5.6c-.7.7-.7 1.8 0 2.5l5.6 5.6c.3.3.8.5 1.2.5s.9-.2 1.2-.5l5.6-5.6c.8-.7.8-1.9.1-2.5zm-1 1.4l-5.6 5.6c-.1.1-.3.1-.4 0l-5.6-5.6c-.1-.1-.1-.3 0-.4l5.6-5.6s.1-.1.2-.1.1 0 .2.1l5.6 5.6c.1.1.1.3 0 .4zm-16.6-.4L10 5.5l-1-1-6.3 6.3c-.7.7-.7 1.8 0 2.5L9 19.5l1.1-1.1-6.3-6.3c-.2 0-.2-.2-.1-.3z"
753 }));
754 /* harmony default export */ const library_symbol = (symbol);
755
756 ;// CONCATENATED MODULE: ./packages/patterns/build-module/components/pattern-convert-button.js
757
758 /**
759 * WordPress dependencies
760 */
761
762
763
764
765
766
767
768
769
770 /**
771 * Internal dependencies
772 */
773
774
775
776
777
778 /**
779 * Menu control to convert block(s) to a pattern block.
780 *
781 * @param {Object} props Component props.
782 * @param {string[]} props.clientIds Client ids of selected blocks.
783 * @param {string} props.rootClientId ID of the currently selected top-level block.
784 * @param {()=>void} props.closeBlockSettingsMenu Callback to close the block settings menu dropdown.
785 * @return {import('react').ComponentType} The menu control or null.
786 */
787 function PatternConvertButton({
788 clientIds,
789 rootClientId,
790 closeBlockSettingsMenu
791 }) {
792 const {
793 createSuccessNotice
794 } = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_notices_namespaceObject.store);
795 const {
796 replaceBlocks
797 } = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_blockEditor_namespaceObject.store);
798 // Ignore reason: false positive of the lint rule.
799 // eslint-disable-next-line @wordpress/no-unused-vars-before-return
800 const {
801 setEditingPattern
802 } = unlock((0,external_wp_data_namespaceObject.useDispatch)(store));
803 const [isModalOpen, setIsModalOpen] = (0,external_wp_element_namespaceObject.useState)(false);
804 const canConvert = (0,external_wp_data_namespaceObject.useSelect)(select => {
805 var _getBlocksByClientId;
806 const {
807 canUser
808 } = select(external_wp_coreData_namespaceObject.store);
809 const {
810 getBlocksByClientId,
811 canInsertBlockType,
812 getBlockRootClientId
813 } = select(external_wp_blockEditor_namespaceObject.store);
814 const rootId = rootClientId || (clientIds.length > 0 ? getBlockRootClientId(clientIds[0]) : undefined);
815 const blocks = (_getBlocksByClientId = getBlocksByClientId(clientIds)) !== null && _getBlocksByClientId !== void 0 ? _getBlocksByClientId : [];
816 const isReusable = blocks.length === 1 && blocks[0] && (0,external_wp_blocks_namespaceObject.isReusableBlock)(blocks[0]) && !!select(external_wp_coreData_namespaceObject.store).getEntityRecord('postType', 'wp_block', blocks[0].attributes.ref);
817 const _canConvert =
818 // Hide when this is already a synced pattern.
819 !isReusable &&
820 // Hide when patterns are disabled.
821 canInsertBlockType('core/block', rootId) && blocks.every(block =>
822 // Guard against the case where a regular block has *just* been converted.
823 !!block &&
824 // Hide on invalid blocks.
825 block.isValid &&
826 // Hide when block doesn't support being made into a pattern.
827 (0,external_wp_blocks_namespaceObject.hasBlockSupport)(block.name, 'reusable', true)) &&
828 // Hide when current doesn't have permission to do that.
829 !!canUser('create', 'blocks');
830 return _canConvert;
831 }, [clientIds, rootClientId]);
832 const {
833 getBlocksByClientId
834 } = (0,external_wp_data_namespaceObject.useSelect)(external_wp_blockEditor_namespaceObject.store);
835 const getContent = (0,external_wp_element_namespaceObject.useCallback)(() => (0,external_wp_blocks_namespaceObject.serialize)(getBlocksByClientId(clientIds)), [getBlocksByClientId, clientIds]);
836 if (!canConvert) {
837 return null;
838 }
839 const handleSuccess = ({
840 pattern
841 }) => {
842 if (pattern.wp_pattern_sync_status !== PATTERN_SYNC_TYPES.unsynced) {
843 const newBlock = (0,external_wp_blocks_namespaceObject.createBlock)('core/block', {
844 ref: pattern.id
845 });
846 replaceBlocks(clientIds, newBlock);
847 setEditingPattern(newBlock.clientId, true);
848 closeBlockSettingsMenu();
849 }
850 createSuccessNotice(pattern.wp_pattern_sync_status === PATTERN_SYNC_TYPES.unsynced ? (0,external_wp_i18n_namespaceObject.sprintf)(
851 // translators: %s: the name the user has given to the pattern.
852 (0,external_wp_i18n_namespaceObject.__)('Unsynced pattern created: %s'), pattern.title.raw) : (0,external_wp_i18n_namespaceObject.sprintf)(
853 // translators: %s: the name the user has given to the pattern.
854 (0,external_wp_i18n_namespaceObject.__)('Synced pattern created: %s'), pattern.title.raw), {
855 type: 'snackbar',
856 id: 'convert-to-pattern-success'
857 });
858 setIsModalOpen(false);
859 };
860 return (0,external_React_namespaceObject.createElement)(external_React_namespaceObject.Fragment, null, (0,external_React_namespaceObject.createElement)(external_wp_components_namespaceObject.MenuItem, {
861 icon: library_symbol,
862 onClick: () => setIsModalOpen(true),
863 "aria-expanded": isModalOpen,
864 "aria-haspopup": "dialog"
865 }, (0,external_wp_i18n_namespaceObject.__)('Create pattern')), isModalOpen && (0,external_React_namespaceObject.createElement)(CreatePatternModal, {
866 content: getContent,
867 onSuccess: pattern => {
868 handleSuccess(pattern);
869 },
870 onError: () => {
871 setIsModalOpen(false);
872 },
873 onClose: () => {
874 setIsModalOpen(false);
875 }
876 }));
877 }
878
879 ;// CONCATENATED MODULE: external ["wp","url"]
880 const external_wp_url_namespaceObject = window["wp"]["url"];
881 ;// CONCATENATED MODULE: ./packages/patterns/build-module/components/patterns-manage-button.js
882
883 /**
884 * WordPress dependencies
885 */
886
887
888
889
890
891
892
893
894 /**
895 * Internal dependencies
896 */
897
898
899 function PatternsManageButton({
900 clientId
901 }) {
902 const {
903 canRemove,
904 isVisible,
905 managePatternsUrl
906 } = (0,external_wp_data_namespaceObject.useSelect)(select => {
907 const {
908 getBlock,
909 canRemoveBlock,
910 getBlockCount,
911 getSettings
912 } = select(external_wp_blockEditor_namespaceObject.store);
913 const {
914 canUser
915 } = select(external_wp_coreData_namespaceObject.store);
916 const reusableBlock = getBlock(clientId);
917 const isBlockTheme = getSettings().__unstableIsBlockBasedTheme;
918 return {
919 canRemove: canRemoveBlock(clientId),
920 isVisible: !!reusableBlock && (0,external_wp_blocks_namespaceObject.isReusableBlock)(reusableBlock) && !!canUser('update', 'blocks', reusableBlock.attributes.ref),
921 innerBlockCount: getBlockCount(clientId),
922 // The site editor and templates both check whether the user
923 // has edit_theme_options capabilities. We can leverage that here
924 // and omit the manage patterns link if the user can't access it.
925 managePatternsUrl: isBlockTheme && canUser('read', 'templates') ? (0,external_wp_url_namespaceObject.addQueryArgs)('site-editor.php', {
926 path: '/patterns'
927 }) : (0,external_wp_url_namespaceObject.addQueryArgs)('edit.php', {
928 post_type: 'wp_block'
929 })
930 };
931 }, [clientId]);
932
933 // Ignore reason: false positive of the lint rule.
934 // eslint-disable-next-line @wordpress/no-unused-vars-before-return
935 const {
936 convertSyncedPatternToStatic
937 } = unlock((0,external_wp_data_namespaceObject.useDispatch)(store));
938 if (!isVisible) {
939 return null;
940 }
941 return (0,external_React_namespaceObject.createElement)(external_React_namespaceObject.Fragment, null, canRemove && (0,external_React_namespaceObject.createElement)(external_wp_components_namespaceObject.MenuItem, {
942 onClick: () => convertSyncedPatternToStatic(clientId)
943 }, (0,external_wp_i18n_namespaceObject.__)('Detach')), (0,external_React_namespaceObject.createElement)(external_wp_components_namespaceObject.MenuItem, {
944 href: managePatternsUrl
945 }, (0,external_wp_i18n_namespaceObject.__)('Manage patterns')));
946 }
947 /* harmony default export */ const patterns_manage_button = (PatternsManageButton);
948
949 ;// CONCATENATED MODULE: ./packages/patterns/build-module/components/index.js
950
951 /**
952 * WordPress dependencies
953 */
954
955
956 /**
957 * Internal dependencies
958 */
959
960
961 function PatternsMenuItems({
962 rootClientId
963 }) {
964 return (0,external_React_namespaceObject.createElement)(external_wp_blockEditor_namespaceObject.BlockSettingsMenuControls, null, ({
965 selectedClientIds,
966 onClose
967 }) => (0,external_React_namespaceObject.createElement)(external_React_namespaceObject.Fragment, null, (0,external_React_namespaceObject.createElement)(PatternConvertButton, {
968 clientIds: selectedClientIds,
969 rootClientId: rootClientId,
970 closeBlockSettingsMenu: onClose
971 }), selectedClientIds.length === 1 && (0,external_React_namespaceObject.createElement)(patterns_manage_button, {
972 clientId: selectedClientIds[0]
973 })));
974 }
975
976 ;// CONCATENATED MODULE: external ["wp","a11y"]
977 const external_wp_a11y_namespaceObject = window["wp"]["a11y"];
978 ;// CONCATENATED MODULE: ./packages/patterns/build-module/components/rename-pattern-category-modal.js
979
980 /**
981 * WordPress dependencies
982 */
983
984
985
986
987
988
989
990
991
992 /**
993 * Internal dependencies
994 */
995
996 function RenamePatternCategoryModal({
997 category,
998 existingCategories,
999 onClose,
1000 onError,
1001 onSuccess,
1002 ...props
1003 }) {
1004 const id = (0,external_wp_element_namespaceObject.useId)();
1005 const textControlRef = (0,external_wp_element_namespaceObject.useRef)();
1006 const [name, setName] = (0,external_wp_element_namespaceObject.useState)((0,external_wp_htmlEntities_namespaceObject.decodeEntities)(category.name));
1007 const [isSaving, setIsSaving] = (0,external_wp_element_namespaceObject.useState)(false);
1008 const [validationMessage, setValidationMessage] = (0,external_wp_element_namespaceObject.useState)(false);
1009 const validationMessageId = validationMessage ? `patterns-rename-pattern-category-modal__validation-message-${id}` : undefined;
1010 const {
1011 saveEntityRecord,
1012 invalidateResolution
1013 } = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_coreData_namespaceObject.store);
1014 const {
1015 createErrorNotice,
1016 createSuccessNotice
1017 } = (0,external_wp_data_namespaceObject.useDispatch)(external_wp_notices_namespaceObject.store);
1018 const onChange = newName => {
1019 if (validationMessage) {
1020 setValidationMessage(undefined);
1021 }
1022 setName(newName);
1023 };
1024 const onSave = async event => {
1025 event.preventDefault();
1026 if (isSaving) {
1027 return;
1028 }
1029 if (!name || name === category.name) {
1030 const message = (0,external_wp_i18n_namespaceObject.__)('Please enter a new name for this category.');
1031 (0,external_wp_a11y_namespaceObject.speak)(message, 'assertive');
1032 setValidationMessage(message);
1033 textControlRef.current?.focus();
1034 return;
1035 }
1036
1037 // Check existing categories to avoid creating duplicates.
1038 if (existingCategories.patternCategories.find(existingCategory => {
1039 // Compare the id so that the we don't disallow the user changing the case of their current category
1040 // (i.e. renaming 'test' to 'Test').
1041 return existingCategory.id !== category.id && existingCategory.label.toLowerCase() === name.toLowerCase();
1042 })) {
1043 const message = (0,external_wp_i18n_namespaceObject.__)('This category already exists. Please use a different name.');
1044 (0,external_wp_a11y_namespaceObject.speak)(message, 'assertive');
1045 setValidationMessage(message);
1046 textControlRef.current?.focus();
1047 return;
1048 }
1049 try {
1050 setIsSaving(true);
1051
1052 // User pattern category properties may differ as they can be
1053 // normalized for use alongside template part areas, core pattern
1054 // categories etc. As a result we won't just destructure the passed
1055 // category object.
1056 const savedRecord = await saveEntityRecord('taxonomy', CATEGORY_SLUG, {
1057 id: category.id,
1058 slug: category.slug,
1059 name
1060 });
1061 invalidateResolution('getUserPatternCategories');
1062 onSuccess?.(savedRecord);
1063 onClose();
1064 createSuccessNotice((0,external_wp_i18n_namespaceObject.__)('Pattern category renamed.'), {
1065 type: 'snackbar',
1066 id: 'pattern-category-update'
1067 });
1068 } catch (error) {
1069 onError?.();
1070 createErrorNotice(error.message, {
1071 type: 'snackbar',
1072 id: 'pattern-category-update'
1073 });
1074 } finally {
1075 setIsSaving(false);
1076 setName('');
1077 }
1078 };
1079 const onRequestClose = () => {
1080 onClose();
1081 setName('');
1082 };
1083 return (0,external_React_namespaceObject.createElement)(external_wp_components_namespaceObject.Modal, {
1084 title: (0,external_wp_i18n_namespaceObject.__)('Rename'),
1085 onRequestClose: onRequestClose,
1086 ...props
1087 }, (0,external_React_namespaceObject.createElement)("form", {
1088 onSubmit: onSave
1089 }, (0,external_React_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalVStack, {
1090 spacing: "5"
1091 }, (0,external_React_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalVStack, {
1092 spacing: "2"
1093 }, (0,external_React_namespaceObject.createElement)(external_wp_components_namespaceObject.TextControl, {
1094 ref: textControlRef,
1095 __nextHasNoMarginBottom: true,
1096 __next40pxDefaultSize: true,
1097 label: (0,external_wp_i18n_namespaceObject.__)('Name'),
1098 value: name,
1099 onChange: onChange,
1100 "aria-describedby": validationMessageId,
1101 required: true
1102 }), validationMessage && (0,external_React_namespaceObject.createElement)("span", {
1103 className: "patterns-rename-pattern-category-modal__validation-message",
1104 id: validationMessageId
1105 }, validationMessage)), (0,external_React_namespaceObject.createElement)(external_wp_components_namespaceObject.__experimentalHStack, {
1106 justify: "right"
1107 }, (0,external_React_namespaceObject.createElement)(external_wp_components_namespaceObject.Button, {
1108 __next40pxDefaultSize: true,
1109 variant: "tertiary",
1110 onClick: onRequestClose
1111 }, (0,external_wp_i18n_namespaceObject.__)('Cancel')), (0,external_React_namespaceObject.createElement)(external_wp_components_namespaceObject.Button, {
1112 __next40pxDefaultSize: true,
1113 variant: "primary",
1114 type: "submit",
1115 "aria-disabled": !name || name === category.name || isSaving,
1116 isBusy: isSaving
1117 }, (0,external_wp_i18n_namespaceObject.__)('Save'))))));
1118 }
1119
1120 ;// CONCATENATED MODULE: ./node_modules/nanoid/index.browser.js
1121
1122 let random = bytes => crypto.getRandomValues(new Uint8Array(bytes))
1123 let customRandom = (alphabet, defaultSize, getRandom) => {
1124 let mask = (2 << (Math.log(alphabet.length - 1) / Math.LN2)) - 1
1125 let step = -~((1.6 * mask * defaultSize) / alphabet.length)
1126 return (size = defaultSize) => {
1127 let id = ''
1128 while (true) {
1129 let bytes = getRandom(step)
1130 let j = step
1131 while (j--) {
1132 id += alphabet[bytes[j] & mask] || ''
1133 if (id.length === size) return id
1134 }
1135 }
1136 }
1137 }
1138 let customAlphabet = (alphabet, size = 21) =>
1139 customRandom(alphabet, size, random)
1140 let nanoid = (size = 21) =>
1141 crypto.getRandomValues(new Uint8Array(size)).reduce((id, byte) => {
1142 byte &= 63
1143 if (byte < 36) {
1144 id += byte.toString(36)
1145 } else if (byte < 62) {
1146 id += (byte - 26).toString(36).toUpperCase()
1147 } else if (byte > 62) {
1148 id += '-'
1149 } else {
1150 id += '_'
1151 }
1152 return id
1153 }, '')
1154
1155
1156 ;// CONCATENATED MODULE: ./packages/patterns/build-module/components/partial-syncing-controls.js
1157
1158 /**
1159 * External dependencies
1160 */
1161
1162
1163 /**
1164 * WordPress dependencies
1165 */
1166
1167
1168
1169
1170 /**
1171 * Internal dependencies
1172 */
1173
1174 function PartialSyncingControls({
1175 name,
1176 attributes,
1177 setAttributes
1178 }) {
1179 const syncedAttributes = PARTIAL_SYNCING_SUPPORTED_BLOCKS[name];
1180 const attributeSources = Object.keys(syncedAttributes).map(attributeName => attributes.metadata?.bindings?.[attributeName]?.source);
1181 const isConnectedToOtherSources = attributeSources.every(source => source && source !== 'core/pattern-overrides');
1182
1183 // Render nothing if all supported attributes are connected to other sources.
1184 if (isConnectedToOtherSources) {
1185 return null;
1186 }
1187 function updateBindings(isChecked) {
1188 let updatedBindings = {
1189 ...attributes?.metadata?.bindings
1190 };
1191 if (!isChecked) {
1192 for (const attributeName of Object.keys(syncedAttributes)) {
1193 if (updatedBindings[attributeName]?.source === 'core/pattern-overrides') {
1194 delete updatedBindings[attributeName];
1195 }
1196 }
1197 if (!Object.keys(updatedBindings).length) {
1198 updatedBindings = undefined;
1199 }
1200 setAttributes({
1201 metadata: {
1202 ...attributes.metadata,
1203 bindings: updatedBindings
1204 }
1205 });
1206 return;
1207 }
1208 for (const attributeName of Object.keys(syncedAttributes)) {
1209 if (!updatedBindings[attributeName]) {
1210 updatedBindings[attributeName] = {
1211 source: 'core/pattern-overrides'
1212 };
1213 }
1214 }
1215 if (typeof attributes.metadata?.id === 'string') {
1216 setAttributes({
1217 metadata: {
1218 ...attributes.metadata,
1219 bindings: updatedBindings
1220 }
1221 });
1222 return;
1223 }
1224 const id = nanoid(6);
1225 setAttributes({
1226 metadata: {
1227 ...attributes.metadata,
1228 id,
1229 bindings: updatedBindings
1230 }
1231 });
1232 }
1233 return (0,external_React_namespaceObject.createElement)(external_wp_blockEditor_namespaceObject.InspectorControls, {
1234 group: "advanced"
1235 }, (0,external_React_namespaceObject.createElement)(external_wp_components_namespaceObject.BaseControl, {
1236 __nextHasNoMarginBottom: true
1237 }, (0,external_React_namespaceObject.createElement)(external_wp_components_namespaceObject.BaseControl.VisualLabel, null, (0,external_wp_i18n_namespaceObject.__)('Pattern overrides')), (0,external_React_namespaceObject.createElement)(external_wp_components_namespaceObject.CheckboxControl, {
1238 __nextHasNoMarginBottom: true,
1239 label: (0,external_wp_i18n_namespaceObject.__)('Allow instance overrides'),
1240 checked: attributeSources.some(source => source === 'core/pattern-overrides'),
1241 onChange: isChecked => {
1242 updateBindings(isChecked);
1243 }
1244 })));
1245 }
1246 /* harmony default export */ const partial_syncing_controls = (PartialSyncingControls);
1247
1248 ;// CONCATENATED MODULE: ./packages/patterns/build-module/private-apis.js
1249 /**
1250 * Internal dependencies
1251 */
1252
1253
1254
1255
1256
1257
1258
1259
1260 const privateApis = {};
1261 lock(privateApis, {
1262 CreatePatternModal: CreatePatternModal,
1263 CreatePatternModalContents: CreatePatternModalContents,
1264 DuplicatePatternModal: DuplicatePatternModal,
1265 useDuplicatePatternProps: useDuplicatePatternProps,
1266 RenamePatternModal: RenamePatternModal,
1267 PatternsMenuItems: PatternsMenuItems,
1268 RenamePatternCategoryModal: RenamePatternCategoryModal,
1269 PartialSyncingControls: partial_syncing_controls,
1270 PATTERN_TYPES: PATTERN_TYPES,
1271 PATTERN_DEFAULT_CATEGORY: PATTERN_DEFAULT_CATEGORY,
1272 PATTERN_USER_CATEGORY: PATTERN_USER_CATEGORY,
1273 EXCLUDED_PATTERN_SOURCES: EXCLUDED_PATTERN_SOURCES,
1274 PATTERN_SYNC_TYPES: PATTERN_SYNC_TYPES,
1275 PARTIAL_SYNCING_SUPPORTED_BLOCKS: PARTIAL_SYNCING_SUPPORTED_BLOCKS
1276 });
1277
1278 ;// CONCATENATED MODULE: ./packages/patterns/build-module/index.js
1279 /**
1280 * Internal dependencies
1281 */
1282
1283
1284
1285 (window.wp = window.wp || {}).patterns = __webpack_exports__;
1286 /******/ })()
1287 ;