@wordpress/patterns 1.9.0 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -29,11 +29,7 @@ function getTermLabels( pattern, categories ) {
29
29
  .map( ( category ) => category.label );
30
30
  }
31
31
 
32
- export default function DuplicatePatternModal( {
33
- pattern,
34
- onClose,
35
- onSuccess,
36
- } ) {
32
+ export function useDuplicatePatternProps( { pattern, onSuccess } ) {
37
33
  const { createSuccessNotice } = useDispatch( noticesStore );
38
34
  const categories = useSelect( ( select ) => {
39
35
  const { getUserPatternCategories, getBlockPatternCategories } =
@@ -44,12 +40,10 @@ export default function DuplicatePatternModal( {
44
40
  user: getUserPatternCategories(),
45
41
  };
46
42
  } );
47
-
48
43
  if ( ! pattern ) {
49
44
  return null;
50
45
  }
51
-
52
- const duplicatedProps = {
46
+ return {
53
47
  content: pattern.content,
54
48
  defaultCategories: getTermLabels( pattern, categories ),
55
49
  defaultSyncType:
@@ -63,31 +57,39 @@ export default function DuplicatePatternModal( {
63
57
  ? pattern.title
64
58
  : pattern.title.raw
65
59
  ),
66
- };
60
+ onSuccess: ( { pattern: newPattern } ) => {
61
+ createSuccessNotice(
62
+ sprintf(
63
+ // translators: %s: The new pattern's title e.g. 'Call to action (copy)'.
64
+ __( '"%s" duplicated.' ),
65
+ newPattern.title.raw
66
+ ),
67
+ {
68
+ type: 'snackbar',
69
+ id: 'patterns-create',
70
+ }
71
+ );
67
72
 
68
- function handleOnSuccess( { pattern: newPattern } ) {
69
- createSuccessNotice(
70
- sprintf(
71
- // translators: %s: The new pattern's title e.g. 'Call to action (copy)'.
72
- __( '"%s" duplicated.' ),
73
- newPattern.title.raw
74
- ),
75
- {
76
- type: 'snackbar',
77
- id: 'patterns-create',
78
- }
79
- );
73
+ onSuccess?.( { pattern: newPattern } );
74
+ },
75
+ };
76
+ }
80
77
 
81
- onSuccess?.( { pattern: newPattern } );
78
+ export default function DuplicatePatternModal( {
79
+ pattern,
80
+ onClose,
81
+ onSuccess,
82
+ } ) {
83
+ const duplicatedProps = useDuplicatePatternProps( { pattern, onSuccess } );
84
+ if ( ! pattern ) {
85
+ return null;
82
86
  }
83
-
84
87
  return (
85
88
  <CreatePatternModal
86
89
  modalTitle={ __( 'Duplicate pattern' ) }
87
90
  confirmLabel={ __( 'Duplicate' ) }
88
91
  onClose={ onClose }
89
92
  onError={ onClose }
90
- onSuccess={ handleOnSuccess }
91
93
  { ...duplicatedProps }
92
94
  />
93
95
  );
@@ -17,23 +17,38 @@ import { PARTIAL_SYNCING_SUPPORTED_BLOCKS } from '../constants';
17
17
 
18
18
  function PartialSyncingControls( { name, attributes, setAttributes } ) {
19
19
  const syncedAttributes = PARTIAL_SYNCING_SUPPORTED_BLOCKS[ name ];
20
+ const attributeSources = Object.keys( syncedAttributes ).map(
21
+ ( attributeName ) =>
22
+ attributes.connections?.attributes?.[ attributeName ]?.source
23
+ );
24
+ const isConnectedToOtherSources = attributeSources.every(
25
+ ( source ) => source && source !== 'pattern_attributes'
26
+ );
27
+
28
+ // Render nothing if all supported attributes are connected to other sources.
29
+ if ( isConnectedToOtherSources ) {
30
+ return null;
31
+ }
32
+
33
+ function updateConnections( isChecked ) {
34
+ let updatedConnections = {
35
+ ...attributes.connections,
36
+ attributes: { ...attributes.connections?.attributes },
37
+ };
20
38
 
21
- function updateConnections( attributeName, isChecked ) {
22
39
  if ( ! isChecked ) {
23
- let updatedConnections = {
24
- ...attributes.connections,
25
- attributes: {
26
- ...attributes.connections?.attributes,
27
- [ attributeName ]: undefined,
28
- },
29
- };
30
- if ( Object.keys( updatedConnections.attributes ).length === 1 ) {
31
- updatedConnections.attributes = undefined;
40
+ for ( const attributeName of Object.keys( syncedAttributes ) ) {
41
+ if (
42
+ updatedConnections.attributes[ attributeName ]?.source ===
43
+ 'pattern_attributes'
44
+ ) {
45
+ delete updatedConnections.attributes[ attributeName ];
46
+ }
32
47
  }
33
- if (
34
- Object.keys( updatedConnections ).length === 1 &&
35
- updateConnections.attributes === undefined
36
- ) {
48
+ if ( ! Object.keys( updatedConnections.attributes ).length ) {
49
+ delete updatedConnections.attributes;
50
+ }
51
+ if ( ! Object.keys( updatedConnections ).length ) {
37
52
  updatedConnections = undefined;
38
53
  }
39
54
  setAttributes( {
@@ -42,15 +57,13 @@ function PartialSyncingControls( { name, attributes, setAttributes } ) {
42
57
  return;
43
58
  }
44
59
 
45
- const updatedConnections = {
46
- ...attributes.connections,
47
- attributes: {
48
- ...attributes.connections?.attributes,
49
- [ attributeName ]: {
60
+ for ( const attributeName of Object.keys( syncedAttributes ) ) {
61
+ if ( ! updatedConnections.attributes[ attributeName ] ) {
62
+ updatedConnections.attributes[ attributeName ] = {
50
63
  source: 'pattern_attributes',
51
- },
52
- },
53
- };
64
+ };
65
+ }
66
+ }
54
67
 
55
68
  if ( typeof attributes.metadata?.id === 'string' ) {
56
69
  setAttributes( { connections: updatedConnections } );
@@ -71,25 +84,18 @@ function PartialSyncingControls( { name, attributes, setAttributes } ) {
71
84
  <InspectorControls group="advanced">
72
85
  <BaseControl __nextHasNoMarginBottom>
73
86
  <BaseControl.VisualLabel>
74
- { __( 'Synced attributes' ) }
87
+ { __( 'Pattern overrides' ) }
75
88
  </BaseControl.VisualLabel>
76
- { Object.entries( syncedAttributes ).map(
77
- ( [ attributeName, label ] ) => (
78
- <CheckboxControl
79
- key={ attributeName }
80
- __nextHasNoMarginBottom
81
- label={ label }
82
- checked={
83
- attributes.connections?.attributes?.[
84
- attributeName
85
- ]?.source === 'pattern_attributes'
86
- }
87
- onChange={ ( isChecked ) => {
88
- updateConnections( attributeName, isChecked );
89
- } }
90
- />
91
- )
92
- ) }
89
+ <CheckboxControl
90
+ __nextHasNoMarginBottom
91
+ label={ __( 'Allow instance overrides' ) }
92
+ checked={ attributeSources.some(
93
+ ( source ) => source === 'pattern_attributes'
94
+ ) }
95
+ onChange={ ( isChecked ) => {
96
+ updateConnections( isChecked );
97
+ } }
98
+ />
93
99
  </BaseControl>
94
100
  </InspectorControls>
95
101
  );
@@ -2,8 +2,14 @@
2
2
  * Internal dependencies
3
3
  */
4
4
  import { lock } from './lock-unlock';
5
- import CreatePatternModal from './components/create-pattern-modal';
6
- import DuplicatePatternModal from './components/duplicate-pattern-modal';
5
+ import {
6
+ default as CreatePatternModal,
7
+ CreatePatternModalContents,
8
+ } from './components/create-pattern-modal';
9
+ import {
10
+ default as DuplicatePatternModal,
11
+ useDuplicatePatternProps,
12
+ } from './components/duplicate-pattern-modal';
7
13
  import RenamePatternModal from './components/rename-pattern-modal';
8
14
  import PatternsMenuItems from './components';
9
15
  import RenamePatternCategoryModal from './components/rename-pattern-category-modal';
@@ -20,7 +26,9 @@ import {
20
26
  export const privateApis = {};
21
27
  lock( privateApis, {
22
28
  CreatePatternModal,
29
+ CreatePatternModalContents,
23
30
  DuplicatePatternModal,
31
+ useDuplicatePatternProps,
24
32
  RenamePatternModal,
25
33
  PatternsMenuItems,
26
34
  RenamePatternCategoryModal,