@wordpress/patterns 1.9.0 → 1.9.1-next.79a6196f.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,52 +17,71 @@ 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.metadata?.bindings?.[ attributeName ]?.source?.name
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 updateBindings( isChecked ) {
34
+ let updatedBindings = {
35
+ ...attributes?.metadata?.bindings,
36
+ };
20
37
 
21
- function updateConnections( attributeName, isChecked ) {
22
38
  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;
39
+ for ( const attributeName of Object.keys( syncedAttributes ) ) {
40
+ if (
41
+ updatedBindings[ attributeName ]?.source?.name ===
42
+ 'pattern_attributes'
43
+ ) {
44
+ delete updatedBindings[ attributeName ];
45
+ }
32
46
  }
33
- if (
34
- Object.keys( updatedConnections ).length === 1 &&
35
- updateConnections.attributes === undefined
36
- ) {
37
- updatedConnections = undefined;
47
+ if ( ! Object.keys( updatedBindings ).length ) {
48
+ updatedBindings = undefined;
38
49
  }
39
50
  setAttributes( {
40
- connections: updatedConnections,
51
+ metadata: {
52
+ ...attributes.metadata,
53
+ bindings: updatedBindings,
54
+ },
41
55
  } );
42
56
  return;
43
57
  }
44
58
 
45
- const updatedConnections = {
46
- ...attributes.connections,
47
- attributes: {
48
- ...attributes.connections?.attributes,
49
- [ attributeName ]: {
50
- source: 'pattern_attributes',
51
- },
52
- },
53
- };
59
+ for ( const attributeName of Object.keys( syncedAttributes ) ) {
60
+ if ( ! updatedBindings[ attributeName ] ) {
61
+ updatedBindings[ attributeName ] = {
62
+ source: {
63
+ name: 'pattern_attributes',
64
+ },
65
+ };
66
+ }
67
+ }
54
68
 
55
69
  if ( typeof attributes.metadata?.id === 'string' ) {
56
- setAttributes( { connections: updatedConnections } );
70
+ setAttributes( {
71
+ metadata: {
72
+ ...attributes.metadata,
73
+ bindings: updatedBindings,
74
+ },
75
+ } );
57
76
  return;
58
77
  }
59
78
 
60
79
  const id = nanoid( 6 );
61
80
  setAttributes( {
62
- connections: updatedConnections,
63
81
  metadata: {
64
82
  ...attributes.metadata,
65
83
  id,
84
+ bindings: updatedBindings,
66
85
  },
67
86
  } );
68
87
  }
@@ -71,25 +90,18 @@ function PartialSyncingControls( { name, attributes, setAttributes } ) {
71
90
  <InspectorControls group="advanced">
72
91
  <BaseControl __nextHasNoMarginBottom>
73
92
  <BaseControl.VisualLabel>
74
- { __( 'Synced attributes' ) }
93
+ { __( 'Pattern overrides' ) }
75
94
  </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
- ) }
95
+ <CheckboxControl
96
+ __nextHasNoMarginBottom
97
+ label={ __( 'Allow instance overrides' ) }
98
+ checked={ attributeSources.some(
99
+ ( source ) => source === 'pattern_attributes'
100
+ ) }
101
+ onChange={ ( isChecked ) => {
102
+ updateBindings( isChecked );
103
+ } }
104
+ />
93
105
  </BaseControl>
94
106
  </InspectorControls>
95
107
  );
@@ -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,