@wordpress/patterns 2.30.1-next.836ecdcae.0 → 2.31.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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 2.31.0 (2025-09-17)
6
+
5
7
  ## 2.30.0 (2025-09-03)
6
8
 
7
9
  ## 2.29.0 (2025-08-20)
@@ -44,7 +44,8 @@ var _jsxRuntime = require("react/jsx-runtime");
44
44
  createSuccessNotice
45
45
  } = (0, _data.useDispatch)(_notices.store);
46
46
  const {
47
- replaceBlocks
47
+ replaceBlocks,
48
+ updateBlockAttributes
48
49
  } = (0, _data.useDispatch)(_blockEditor.store);
49
50
  // Ignore reason: false positive of the lint rule.
50
51
  // eslint-disable-next-line @wordpress/no-unused-vars-before-return
@@ -52,6 +53,9 @@ var _jsxRuntime = require("react/jsx-runtime");
52
53
  setEditingPattern
53
54
  } = (0, _lockUnlock.unlock)((0, _data.useDispatch)(_store.store));
54
55
  const [isModalOpen, setIsModalOpen] = (0, _element.useState)(false);
56
+ const {
57
+ getBlockAttributes
58
+ } = (0, _data.useSelect)(_blockEditor.store);
55
59
  const canConvert = (0, _data.useSelect)(select => {
56
60
  var _getBlocksByClientId;
57
61
  const {
@@ -73,10 +77,11 @@ var _jsxRuntime = require("react/jsx-runtime");
73
77
  // If the block has a parent, check with false as default, otherwise with true.
74
78
  return (0, _blocks.hasBlockSupport)(blockName, 'reusable', !hasParent);
75
79
  };
76
- const isReusable = blocks.length === 1 && blocks[0] && (0, _blocks.isReusableBlock)(blocks[0]) && !!select(_coreData.store).getEntityRecord('postType', 'wp_block', blocks[0].attributes.ref);
80
+ const isSyncedPattern = blocks.length === 1 && blocks[0] && (0, _blocks.isReusableBlock)(blocks[0]) && !!select(_coreData.store).getEntityRecord('postType', 'wp_block', blocks[0].attributes.ref);
81
+ const isUnsyncedPattern = window?.__experimentalContentOnlyPatternInsertion && blocks.length === 1 && blocks?.[0]?.attributes?.metadata?.patternName;
77
82
  const _canConvert =
78
- // Hide when this is already a synced pattern.
79
- !isReusable &&
83
+ // Hide when this is already a pattern.
84
+ !isUnsyncedPattern && !isSyncedPattern &&
80
85
  // Hide when patterns are disabled.
81
86
  canInsertBlockType('core/block', rootId) && blocks.every(block =>
82
87
  // Guard against the case where a regular block has *just* been converted.
@@ -103,7 +108,18 @@ var _jsxRuntime = require("react/jsx-runtime");
103
108
  const handleSuccess = ({
104
109
  pattern
105
110
  }) => {
106
- if (pattern.wp_pattern_sync_status !== _constants.PATTERN_SYNC_TYPES.unsynced) {
111
+ if (pattern.wp_pattern_sync_status === _constants.PATTERN_SYNC_TYPES.unsynced) {
112
+ if (clientIds?.length === 1) {
113
+ const existingAttributes = getBlockAttributes(clientIds[0]);
114
+ updateBlockAttributes(clientIds[0], {
115
+ metadata: {
116
+ ...(existingAttributes?.metadata ? existingAttributes.metadata : {}),
117
+ patternName: `core/block/${pattern.id}`,
118
+ name: pattern.title.raw
119
+ }
120
+ });
121
+ }
122
+ } else {
107
123
  const newBlock = (0, _blocks.createBlock)('core/block', {
108
124
  ref: pattern.id
109
125
  });
@@ -1 +1 @@
1
- {"version":3,"names":["_blocks","require","_blockEditor","_element","_components","_icons","_data","_coreData","_i18n","_notices","_store","_createPatternModal","_interopRequireDefault","_lockUnlock","_constants","_jsxRuntime","PatternConvertButton","clientIds","rootClientId","closeBlockSettingsMenu","createSuccessNotice","useDispatch","noticesStore","replaceBlocks","blockEditorStore","setEditingPattern","unlock","patternsStore","isModalOpen","setIsModalOpen","useState","canConvert","useSelect","select","_getBlocksByClientId","canUser","coreStore","getBlocksByClientId","canInsertBlockType","getBlockRootClientId","rootId","length","undefined","blocks","hasReusableBlockSupport","blockName","blockType","getBlockType","hasParent","hasBlockSupport","isReusable","isReusableBlock","getEntityRecord","attributes","ref","_canConvert","every","block","isValid","name","kind","getContent","useCallback","serialize","handleSuccess","pattern","wp_pattern_sync_status","PATTERN_SYNC_TYPES","unsynced","newBlock","createBlock","id","clientId","sprintf","__","title","raw","type","jsxs","Fragment","children","jsx","MenuItem","icon","symbol","onClick","default","content","onSuccess","onError","onClose"],"sources":["@wordpress/patterns/src/components/pattern-convert-button.js"],"sourcesContent":["/**\n * WordPress dependencies\n */\nimport {\n\thasBlockSupport,\n\tisReusableBlock,\n\tcreateBlock,\n\tserialize,\n\tgetBlockType,\n} from '@wordpress/blocks';\nimport { store as blockEditorStore } from '@wordpress/block-editor';\nimport { useState, useCallback } from '@wordpress/element';\nimport { MenuItem } from '@wordpress/components';\nimport { symbol } from '@wordpress/icons';\nimport { useSelect, useDispatch } from '@wordpress/data';\nimport { store as coreStore } from '@wordpress/core-data';\nimport { __, sprintf } from '@wordpress/i18n';\nimport { store as noticesStore } from '@wordpress/notices';\n/**\n * Internal dependencies\n */\nimport { store as patternsStore } from '../store';\nimport CreatePatternModal from './create-pattern-modal';\nimport { unlock } from '../lock-unlock';\nimport { PATTERN_SYNC_TYPES } from '../constants';\n\n/**\n * Menu control to convert block(s) to a pattern block.\n *\n * @param {Object} props Component props.\n * @param {string[]} props.clientIds Client ids of selected blocks.\n * @param {string} props.rootClientId ID of the currently selected top-level block.\n * @param {()=>void} props.closeBlockSettingsMenu Callback to close the block settings menu dropdown.\n * @return {import('react').ComponentType} The menu control or null.\n */\nexport default function PatternConvertButton( {\n\tclientIds,\n\trootClientId,\n\tcloseBlockSettingsMenu,\n} ) {\n\tconst { createSuccessNotice } = useDispatch( noticesStore );\n\tconst { replaceBlocks } = useDispatch( blockEditorStore );\n\t// Ignore reason: false positive of the lint rule.\n\t// eslint-disable-next-line @wordpress/no-unused-vars-before-return\n\tconst { setEditingPattern } = unlock( useDispatch( patternsStore ) );\n\tconst [ isModalOpen, setIsModalOpen ] = useState( false );\n\tconst canConvert = useSelect(\n\t\t( select ) => {\n\t\t\tconst { canUser } = select( coreStore );\n\t\t\tconst {\n\t\t\t\tgetBlocksByClientId,\n\t\t\t\tcanInsertBlockType,\n\t\t\t\tgetBlockRootClientId,\n\t\t\t} = select( blockEditorStore );\n\n\t\t\tconst rootId =\n\t\t\t\trootClientId ||\n\t\t\t\t( clientIds.length > 0\n\t\t\t\t\t? getBlockRootClientId( clientIds[ 0 ] )\n\t\t\t\t\t: undefined );\n\n\t\t\tconst blocks = getBlocksByClientId( clientIds ) ?? [];\n\n\t\t\t// Check if the block has reusable support defined.\n\t\t\tconst hasReusableBlockSupport = ( blockName ) => {\n\t\t\t\tconst blockType = getBlockType( blockName );\n\t\t\t\tconst hasParent = blockType && 'parent' in blockType;\n\n\t\t\t\t// If the block has a parent, check with false as default, otherwise with true.\n\t\t\t\treturn hasBlockSupport( blockName, 'reusable', ! hasParent );\n\t\t\t};\n\n\t\t\tconst isReusable =\n\t\t\t\tblocks.length === 1 &&\n\t\t\t\tblocks[ 0 ] &&\n\t\t\t\tisReusableBlock( blocks[ 0 ] ) &&\n\t\t\t\t!! select( coreStore ).getEntityRecord(\n\t\t\t\t\t'postType',\n\t\t\t\t\t'wp_block',\n\t\t\t\t\tblocks[ 0 ].attributes.ref\n\t\t\t\t);\n\n\t\t\tconst _canConvert =\n\t\t\t\t// Hide when this is already a synced pattern.\n\t\t\t\t! isReusable &&\n\t\t\t\t// Hide when patterns are disabled.\n\t\t\t\tcanInsertBlockType( 'core/block', rootId ) &&\n\t\t\t\tblocks.every(\n\t\t\t\t\t( block ) =>\n\t\t\t\t\t\t// Guard against the case where a regular block has *just* been converted.\n\t\t\t\t\t\t!! block &&\n\t\t\t\t\t\t// Hide on invalid blocks.\n\t\t\t\t\t\tblock.isValid &&\n\t\t\t\t\t\t// Hide when block doesn't support being made into a pattern.\n\t\t\t\t\t\thasReusableBlockSupport( block.name )\n\t\t\t\t) &&\n\t\t\t\t// Hide when current doesn't have permission to do that.\n\t\t\t\t// Blocks refers to the wp_block post type, this checks the ability to create a post of that type.\n\t\t\t\t!! canUser( 'create', {\n\t\t\t\t\tkind: 'postType',\n\t\t\t\t\tname: 'wp_block',\n\t\t\t\t} );\n\n\t\t\treturn _canConvert;\n\t\t},\n\t\t[ clientIds, rootClientId ]\n\t);\n\tconst { getBlocksByClientId } = useSelect( blockEditorStore );\n\tconst getContent = useCallback(\n\t\t() => serialize( getBlocksByClientId( clientIds ) ),\n\t\t[ getBlocksByClientId, clientIds ]\n\t);\n\n\tif ( ! canConvert ) {\n\t\treturn null;\n\t}\n\n\tconst handleSuccess = ( { pattern } ) => {\n\t\tif ( pattern.wp_pattern_sync_status !== PATTERN_SYNC_TYPES.unsynced ) {\n\t\t\tconst newBlock = createBlock( 'core/block', {\n\t\t\t\tref: pattern.id,\n\t\t\t} );\n\n\t\t\treplaceBlocks( clientIds, newBlock );\n\t\t\tsetEditingPattern( newBlock.clientId, true );\n\t\t\tcloseBlockSettingsMenu();\n\t\t}\n\n\t\tcreateSuccessNotice(\n\t\t\tpattern.wp_pattern_sync_status === PATTERN_SYNC_TYPES.unsynced\n\t\t\t\t? sprintf(\n\t\t\t\t\t\t// translators: %s: the name the user has given to the pattern.\n\t\t\t\t\t\t__( 'Unsynced pattern created: %s' ),\n\t\t\t\t\t\tpattern.title.raw\n\t\t\t\t )\n\t\t\t\t: sprintf(\n\t\t\t\t\t\t// translators: %s: the name the user has given to the pattern.\n\t\t\t\t\t\t__( 'Synced pattern created: %s' ),\n\t\t\t\t\t\tpattern.title.raw\n\t\t\t\t ),\n\t\t\t{\n\t\t\t\ttype: 'snackbar',\n\t\t\t\tid: 'convert-to-pattern-success',\n\t\t\t}\n\t\t);\n\t\tsetIsModalOpen( false );\n\t};\n\treturn (\n\t\t<>\n\t\t\t<MenuItem\n\t\t\t\ticon={ symbol }\n\t\t\t\tonClick={ () => setIsModalOpen( true ) }\n\t\t\t\taria-expanded={ isModalOpen }\n\t\t\t\taria-haspopup=\"dialog\"\n\t\t\t>\n\t\t\t\t{ __( 'Create pattern' ) }\n\t\t\t</MenuItem>\n\t\t\t{ isModalOpen && (\n\t\t\t\t<CreatePatternModal\n\t\t\t\t\tcontent={ getContent }\n\t\t\t\t\tonSuccess={ ( pattern ) => {\n\t\t\t\t\t\thandleSuccess( pattern );\n\t\t\t\t\t} }\n\t\t\t\t\tonError={ () => {\n\t\t\t\t\t\tsetIsModalOpen( false );\n\t\t\t\t\t} }\n\t\t\t\t\tonClose={ () => {\n\t\t\t\t\t\tsetIsModalOpen( false );\n\t\t\t\t\t} }\n\t\t\t\t/>\n\t\t\t) }\n\t\t</>\n\t);\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_blocks","require","_blockEditor","_element","_components","_icons","_data","_coreData","_i18n","_notices","_store","_createPatternModal","_interopRequireDefault","_lockUnlock","_constants","_jsxRuntime","PatternConvertButton","clientIds","rootClientId","closeBlockSettingsMenu","createSuccessNotice","useDispatch","noticesStore","replaceBlocks","updateBlockAttributes","blockEditorStore","setEditingPattern","unlock","patternsStore","isModalOpen","setIsModalOpen","useState","getBlockAttributes","useSelect","canConvert","select","_getBlocksByClientId","canUser","coreStore","getBlocksByClientId","canInsertBlockType","getBlockRootClientId","rootId","length","undefined","blocks","hasReusableBlockSupport","blockName","blockType","getBlockType","hasParent","hasBlockSupport","isSyncedPattern","isReusableBlock","getEntityRecord","attributes","ref","isUnsyncedPattern","window","__experimentalContentOnlyPatternInsertion","metadata","patternName","_canConvert","every","block","isValid","name","kind","getContent","useCallback","serialize","handleSuccess","pattern","wp_pattern_sync_status","PATTERN_SYNC_TYPES","unsynced","existingAttributes","id","title","raw","newBlock","createBlock","clientId","sprintf","__","type","jsxs","Fragment","children","jsx","MenuItem","icon","symbol","onClick","default","content","onSuccess","onError","onClose"],"sources":["@wordpress/patterns/src/components/pattern-convert-button.js"],"sourcesContent":["/**\n * WordPress dependencies\n */\nimport {\n\thasBlockSupport,\n\tisReusableBlock,\n\tcreateBlock,\n\tserialize,\n\tgetBlockType,\n} from '@wordpress/blocks';\nimport { store as blockEditorStore } from '@wordpress/block-editor';\nimport { useState, useCallback } from '@wordpress/element';\nimport { MenuItem } from '@wordpress/components';\nimport { symbol } from '@wordpress/icons';\nimport { useSelect, useDispatch } from '@wordpress/data';\nimport { store as coreStore } from '@wordpress/core-data';\nimport { __, sprintf } from '@wordpress/i18n';\nimport { store as noticesStore } from '@wordpress/notices';\n/**\n * Internal dependencies\n */\nimport { store as patternsStore } from '../store';\nimport CreatePatternModal from './create-pattern-modal';\nimport { unlock } from '../lock-unlock';\nimport { PATTERN_SYNC_TYPES } from '../constants';\n\n/**\n * Menu control to convert block(s) to a pattern block.\n *\n * @param {Object} props Component props.\n * @param {string[]} props.clientIds Client ids of selected blocks.\n * @param {string} props.rootClientId ID of the currently selected top-level block.\n * @param {()=>void} props.closeBlockSettingsMenu Callback to close the block settings menu dropdown.\n * @return {import('react').ComponentType} The menu control or null.\n */\nexport default function PatternConvertButton( {\n\tclientIds,\n\trootClientId,\n\tcloseBlockSettingsMenu,\n} ) {\n\tconst { createSuccessNotice } = useDispatch( noticesStore );\n\tconst { replaceBlocks, updateBlockAttributes } =\n\t\tuseDispatch( blockEditorStore );\n\t// Ignore reason: false positive of the lint rule.\n\t// eslint-disable-next-line @wordpress/no-unused-vars-before-return\n\tconst { setEditingPattern } = unlock( useDispatch( patternsStore ) );\n\tconst [ isModalOpen, setIsModalOpen ] = useState( false );\n\tconst { getBlockAttributes } = useSelect( blockEditorStore );\n\tconst canConvert = useSelect(\n\t\t( select ) => {\n\t\t\tconst { canUser } = select( coreStore );\n\t\t\tconst {\n\t\t\t\tgetBlocksByClientId,\n\t\t\t\tcanInsertBlockType,\n\t\t\t\tgetBlockRootClientId,\n\t\t\t} = select( blockEditorStore );\n\n\t\t\tconst rootId =\n\t\t\t\trootClientId ||\n\t\t\t\t( clientIds.length > 0\n\t\t\t\t\t? getBlockRootClientId( clientIds[ 0 ] )\n\t\t\t\t\t: undefined );\n\n\t\t\tconst blocks = getBlocksByClientId( clientIds ) ?? [];\n\n\t\t\t// Check if the block has reusable support defined.\n\t\t\tconst hasReusableBlockSupport = ( blockName ) => {\n\t\t\t\tconst blockType = getBlockType( blockName );\n\t\t\t\tconst hasParent = blockType && 'parent' in blockType;\n\n\t\t\t\t// If the block has a parent, check with false as default, otherwise with true.\n\t\t\t\treturn hasBlockSupport( blockName, 'reusable', ! hasParent );\n\t\t\t};\n\n\t\t\tconst isSyncedPattern =\n\t\t\t\tblocks.length === 1 &&\n\t\t\t\tblocks[ 0 ] &&\n\t\t\t\tisReusableBlock( blocks[ 0 ] ) &&\n\t\t\t\t!! select( coreStore ).getEntityRecord(\n\t\t\t\t\t'postType',\n\t\t\t\t\t'wp_block',\n\t\t\t\t\tblocks[ 0 ].attributes.ref\n\t\t\t\t);\n\n\t\t\tconst isUnsyncedPattern =\n\t\t\t\twindow?.__experimentalContentOnlyPatternInsertion &&\n\t\t\t\tblocks.length === 1 &&\n\t\t\t\tblocks?.[ 0 ]?.attributes?.metadata?.patternName;\n\n\t\t\tconst _canConvert =\n\t\t\t\t// Hide when this is already a pattern.\n\t\t\t\t! isUnsyncedPattern &&\n\t\t\t\t! isSyncedPattern &&\n\t\t\t\t// Hide when patterns are disabled.\n\t\t\t\tcanInsertBlockType( 'core/block', rootId ) &&\n\t\t\t\tblocks.every(\n\t\t\t\t\t( block ) =>\n\t\t\t\t\t\t// Guard against the case where a regular block has *just* been converted.\n\t\t\t\t\t\t!! block &&\n\t\t\t\t\t\t// Hide on invalid blocks.\n\t\t\t\t\t\tblock.isValid &&\n\t\t\t\t\t\t// Hide when block doesn't support being made into a pattern.\n\t\t\t\t\t\thasReusableBlockSupport( block.name )\n\t\t\t\t) &&\n\t\t\t\t// Hide when current doesn't have permission to do that.\n\t\t\t\t// Blocks refers to the wp_block post type, this checks the ability to create a post of that type.\n\t\t\t\t!! canUser( 'create', {\n\t\t\t\t\tkind: 'postType',\n\t\t\t\t\tname: 'wp_block',\n\t\t\t\t} );\n\n\t\t\treturn _canConvert;\n\t\t},\n\t\t[ clientIds, rootClientId ]\n\t);\n\tconst { getBlocksByClientId } = useSelect( blockEditorStore );\n\tconst getContent = useCallback(\n\t\t() => serialize( getBlocksByClientId( clientIds ) ),\n\t\t[ getBlocksByClientId, clientIds ]\n\t);\n\n\tif ( ! canConvert ) {\n\t\treturn null;\n\t}\n\n\tconst handleSuccess = ( { pattern } ) => {\n\t\tif ( pattern.wp_pattern_sync_status === PATTERN_SYNC_TYPES.unsynced ) {\n\t\t\tif ( clientIds?.length === 1 ) {\n\t\t\t\tconst existingAttributes = getBlockAttributes( clientIds[ 0 ] );\n\t\t\t\tupdateBlockAttributes( clientIds[ 0 ], {\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\t...( existingAttributes?.metadata\n\t\t\t\t\t\t\t? existingAttributes.metadata\n\t\t\t\t\t\t\t: {} ),\n\t\t\t\t\t\tpatternName: `core/block/${ pattern.id }`,\n\t\t\t\t\t\tname: pattern.title.raw,\n\t\t\t\t\t},\n\t\t\t\t} );\n\t\t\t}\n\t\t} else {\n\t\t\tconst newBlock = createBlock( 'core/block', {\n\t\t\t\tref: pattern.id,\n\t\t\t} );\n\n\t\t\treplaceBlocks( clientIds, newBlock );\n\t\t\tsetEditingPattern( newBlock.clientId, true );\n\t\t\tcloseBlockSettingsMenu();\n\t\t}\n\n\t\tcreateSuccessNotice(\n\t\t\tpattern.wp_pattern_sync_status === PATTERN_SYNC_TYPES.unsynced\n\t\t\t\t? sprintf(\n\t\t\t\t\t\t// translators: %s: the name the user has given to the pattern.\n\t\t\t\t\t\t__( 'Unsynced pattern created: %s' ),\n\t\t\t\t\t\tpattern.title.raw\n\t\t\t\t )\n\t\t\t\t: sprintf(\n\t\t\t\t\t\t// translators: %s: the name the user has given to the pattern.\n\t\t\t\t\t\t__( 'Synced pattern created: %s' ),\n\t\t\t\t\t\tpattern.title.raw\n\t\t\t\t ),\n\t\t\t{\n\t\t\t\ttype: 'snackbar',\n\t\t\t\tid: 'convert-to-pattern-success',\n\t\t\t}\n\t\t);\n\t\tsetIsModalOpen( false );\n\t};\n\treturn (\n\t\t<>\n\t\t\t<MenuItem\n\t\t\t\ticon={ symbol }\n\t\t\t\tonClick={ () => setIsModalOpen( true ) }\n\t\t\t\taria-expanded={ isModalOpen }\n\t\t\t\taria-haspopup=\"dialog\"\n\t\t\t>\n\t\t\t\t{ __( 'Create pattern' ) }\n\t\t\t</MenuItem>\n\t\t\t{ isModalOpen && (\n\t\t\t\t<CreatePatternModal\n\t\t\t\t\tcontent={ getContent }\n\t\t\t\t\tonSuccess={ ( pattern ) => {\n\t\t\t\t\t\thandleSuccess( pattern );\n\t\t\t\t\t} }\n\t\t\t\t\tonError={ () => {\n\t\t\t\t\t\tsetIsModalOpen( false );\n\t\t\t\t\t} }\n\t\t\t\t\tonClose={ () => {\n\t\t\t\t\t\tsetIsModalOpen( false );\n\t\t\t\t\t} }\n\t\t\t\t/>\n\t\t\t) }\n\t\t</>\n\t);\n}\n"],"mappings":"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","ignoreList":[]}
@@ -26,25 +26,36 @@ function PatternsManageButton({
26
26
  clientId
27
27
  }) {
28
28
  const {
29
- canRemove,
29
+ attributes,
30
+ canDetach,
30
31
  isVisible,
31
- managePatternsUrl
32
+ managePatternsUrl,
33
+ isSyncedPattern,
34
+ isUnsyncedPattern
32
35
  } = (0, _data.useSelect)(select => {
33
36
  const {
34
- getBlock,
35
- canRemoveBlock
37
+ canRemoveBlock,
38
+ getBlock
36
39
  } = select(_blockEditor.store);
37
40
  const {
38
41
  canUser
39
42
  } = select(_coreData.store);
40
- const reusableBlock = getBlock(clientId);
43
+ const block = getBlock(clientId);
44
+ const _isUnsyncedPattern = window?.__experimentalContentOnlyPatternInsertion && !!block?.attributes?.metadata?.patternName;
45
+ const _isSyncedPattern = !!block && (0, _blocks.isReusableBlock)(block) && !!canUser('update', {
46
+ kind: 'postType',
47
+ name: 'wp_block',
48
+ id: block.attributes.ref
49
+ });
41
50
  return {
42
- canRemove: canRemoveBlock(clientId),
43
- isVisible: !!reusableBlock && (0, _blocks.isReusableBlock)(reusableBlock) && !!canUser('update', {
44
- kind: 'postType',
45
- name: 'wp_block',
46
- id: reusableBlock.attributes.ref
47
- }),
51
+ attributes: block.attributes,
52
+ // For unsynced patterns, detaching is simply removing the `patternName` attribute.
53
+ // For synced patterns, the `core:block` block is replaced with its inner blocks,
54
+ // so checking whether `canRemoveBlock` is possible is required.
55
+ canDetach: _isUnsyncedPattern || _isSyncedPattern && canRemoveBlock(clientId),
56
+ isUnsyncedPattern: _isUnsyncedPattern,
57
+ isSyncedPattern: _isSyncedPattern,
58
+ isVisible: _isUnsyncedPattern || _isSyncedPattern,
48
59
  // The site editor and templates both check whether the user
49
60
  // has edit_theme_options capabilities. We can leverage that here
50
61
  // and omit the manage patterns link if the user can't access it.
@@ -58,6 +69,9 @@ function PatternsManageButton({
58
69
  })
59
70
  };
60
71
  }, [clientId]);
72
+ const {
73
+ updateBlockAttributes
74
+ } = (0, _data.useDispatch)(_blockEditor.store);
61
75
 
62
76
  // Ignore reason: false positive of the lint rule.
63
77
  // eslint-disable-next-line @wordpress/no-unused-vars-before-return
@@ -68,8 +82,22 @@ function PatternsManageButton({
68
82
  return null;
69
83
  }
70
84
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
71
- children: [canRemove && /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.MenuItem, {
72
- onClick: () => convertSyncedPatternToStatic(clientId),
85
+ children: [canDetach && /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.MenuItem, {
86
+ onClick: () => {
87
+ if (isSyncedPattern) {
88
+ convertSyncedPatternToStatic(clientId);
89
+ }
90
+ if (isUnsyncedPattern) {
91
+ var _attributes$metadata;
92
+ const {
93
+ patternName,
94
+ ...attributesWithoutPatternName
95
+ } = (_attributes$metadata = attributes?.metadata) !== null && _attributes$metadata !== void 0 ? _attributes$metadata : {};
96
+ updateBlockAttributes(clientId, {
97
+ metadata: attributesWithoutPatternName
98
+ });
99
+ }
100
+ },
73
101
  children: (0, _i18n.__)('Detach')
74
102
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.MenuItem, {
75
103
  href: managePatternsUrl,
@@ -1 +1 @@
1
- {"version":3,"names":["_components","require","_i18n","_blocks","_data","_blockEditor","_url","_coreData","_store","_lockUnlock","_jsxRuntime","PatternsManageButton","clientId","canRemove","isVisible","managePatternsUrl","useSelect","select","getBlock","canRemoveBlock","blockEditorStore","canUser","coreStore","reusableBlock","isReusableBlock","kind","name","id","attributes","ref","addQueryArgs","p","post_type","convertSyncedPatternToStatic","unlock","useDispatch","patternsStore","jsxs","Fragment","children","jsx","MenuItem","onClick","__","href","_default","exports","default"],"sources":["@wordpress/patterns/src/components/patterns-manage-button.js"],"sourcesContent":["/**\n * WordPress dependencies\n */\nimport { MenuItem } from '@wordpress/components';\nimport { __ } from '@wordpress/i18n';\nimport { isReusableBlock } from '@wordpress/blocks';\nimport { useSelect, useDispatch } from '@wordpress/data';\nimport { store as blockEditorStore } from '@wordpress/block-editor';\nimport { addQueryArgs } from '@wordpress/url';\nimport { store as coreStore } from '@wordpress/core-data';\n\n/**\n * Internal dependencies\n */\nimport { store as patternsStore } from '../store';\nimport { unlock } from '../lock-unlock';\n\nfunction PatternsManageButton( { clientId } ) {\n\tconst { canRemove, isVisible, managePatternsUrl } = useSelect(\n\t\t( select ) => {\n\t\t\tconst { getBlock, canRemoveBlock } = select( blockEditorStore );\n\t\t\tconst { canUser } = select( coreStore );\n\t\t\tconst reusableBlock = getBlock( clientId );\n\n\t\t\treturn {\n\t\t\t\tcanRemove: canRemoveBlock( clientId ),\n\t\t\t\tisVisible:\n\t\t\t\t\t!! reusableBlock &&\n\t\t\t\t\tisReusableBlock( reusableBlock ) &&\n\t\t\t\t\t!! canUser( 'update', {\n\t\t\t\t\t\tkind: 'postType',\n\t\t\t\t\t\tname: 'wp_block',\n\t\t\t\t\t\tid: reusableBlock.attributes.ref,\n\t\t\t\t\t} ),\n\t\t\t\t// The site editor and templates both check whether the user\n\t\t\t\t// has edit_theme_options capabilities. We can leverage that here\n\t\t\t\t// and omit the manage patterns link if the user can't access it.\n\t\t\t\tmanagePatternsUrl: canUser( 'create', {\n\t\t\t\t\tkind: 'postType',\n\t\t\t\t\tname: 'wp_template',\n\t\t\t\t} )\n\t\t\t\t\t? addQueryArgs( 'site-editor.php', {\n\t\t\t\t\t\t\tp: '/pattern',\n\t\t\t\t\t } )\n\t\t\t\t\t: addQueryArgs( 'edit.php', {\n\t\t\t\t\t\t\tpost_type: 'wp_block',\n\t\t\t\t\t } ),\n\t\t\t};\n\t\t},\n\t\t[ clientId ]\n\t);\n\n\t// Ignore reason: false positive of the lint rule.\n\t// eslint-disable-next-line @wordpress/no-unused-vars-before-return\n\tconst { convertSyncedPatternToStatic } = unlock(\n\t\tuseDispatch( patternsStore )\n\t);\n\n\tif ( ! isVisible ) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<>\n\t\t\t{ canRemove && (\n\t\t\t\t<MenuItem\n\t\t\t\t\tonClick={ () => convertSyncedPatternToStatic( clientId ) }\n\t\t\t\t>\n\t\t\t\t\t{ __( 'Detach' ) }\n\t\t\t\t</MenuItem>\n\t\t\t) }\n\t\t\t<MenuItem href={ managePatternsUrl }>\n\t\t\t\t{ __( 'Manage patterns' ) }\n\t\t\t</MenuItem>\n\t\t</>\n\t);\n}\n\nexport default PatternsManageButton;\n"],"mappings":";;;;;;AAGA,IAAAA,WAAA,GAAAC,OAAA;AACA,IAAAC,KAAA,GAAAD,OAAA;AACA,IAAAE,OAAA,GAAAF,OAAA;AACA,IAAAG,KAAA,GAAAH,OAAA;AACA,IAAAI,YAAA,GAAAJ,OAAA;AACA,IAAAK,IAAA,GAAAL,OAAA;AACA,IAAAM,SAAA,GAAAN,OAAA;AAKA,IAAAO,MAAA,GAAAP,OAAA;AACA,IAAAQ,WAAA,GAAAR,OAAA;AAAwC,IAAAS,WAAA,GAAAT,OAAA;AAfxC;AACA;AACA;;AASA;AACA;AACA;;AAIA,SAASU,oBAAoBA,CAAE;EAAEC;AAAS,CAAC,EAAG;EAC7C,MAAM;IAAEC,SAAS;IAAEC,SAAS;IAAEC;EAAkB,CAAC,GAAG,IAAAC,eAAS,EAC1DC,MAAM,IAAM;IACb,MAAM;MAAEC,QAAQ;MAAEC;IAAe,CAAC,GAAGF,MAAM,CAAEG,kBAAiB,CAAC;IAC/D,MAAM;MAAEC;IAAQ,CAAC,GAAGJ,MAAM,CAAEK,eAAU,CAAC;IACvC,MAAMC,aAAa,GAAGL,QAAQ,CAAEN,QAAS,CAAC;IAE1C,OAAO;MACNC,SAAS,EAAEM,cAAc,CAAEP,QAAS,CAAC;MACrCE,SAAS,EACR,CAAC,CAAES,aAAa,IAChB,IAAAC,uBAAe,EAAED,aAAc,CAAC,IAChC,CAAC,CAAEF,OAAO,CAAE,QAAQ,EAAE;QACrBI,IAAI,EAAE,UAAU;QAChBC,IAAI,EAAE,UAAU;QAChBC,EAAE,EAAEJ,aAAa,CAACK,UAAU,CAACC;MAC9B,CAAE,CAAC;MACJ;MACA;MACA;MACAd,iBAAiB,EAAEM,OAAO,CAAE,QAAQ,EAAE;QACrCI,IAAI,EAAE,UAAU;QAChBC,IAAI,EAAE;MACP,CAAE,CAAC,GACA,IAAAI,iBAAY,EAAE,iBAAiB,EAAE;QACjCC,CAAC,EAAE;MACH,CAAE,CAAC,GACH,IAAAD,iBAAY,EAAE,UAAU,EAAE;QAC1BE,SAAS,EAAE;MACX,CAAE;IACN,CAAC;EACF,CAAC,EACD,CAAEpB,QAAQ,CACX,CAAC;;EAED;EACA;EACA,MAAM;IAAEqB;EAA6B,CAAC,GAAG,IAAAC,kBAAM,EAC9C,IAAAC,iBAAW,EAAEC,YAAc,CAC5B,CAAC;EAED,IAAK,CAAEtB,SAAS,EAAG;IAClB,OAAO,IAAI;EACZ;EAEA,oBACC,IAAAJ,WAAA,CAAA2B,IAAA,EAAA3B,WAAA,CAAA4B,QAAA;IAAAC,QAAA,GACG1B,SAAS,iBACV,IAAAH,WAAA,CAAA8B,GAAA,EAACxC,WAAA,CAAAyC,QAAQ;MACRC,OAAO,EAAGA,CAAA,KAAMT,4BAA4B,CAAErB,QAAS,CAAG;MAAA2B,QAAA,EAExD,IAAAI,QAAE,EAAE,QAAS;IAAC,CACP,CACV,eACD,IAAAjC,WAAA,CAAA8B,GAAA,EAACxC,WAAA,CAAAyC,QAAQ;MAACG,IAAI,EAAG7B,iBAAmB;MAAAwB,QAAA,EACjC,IAAAI,QAAE,EAAE,iBAAkB;IAAC,CAChB,CAAC;EAAA,CACV,CAAC;AAEL;AAAC,IAAAE,QAAA,GAAAC,OAAA,CAAAC,OAAA,GAEcpC,oBAAoB","ignoreList":[]}
1
+ {"version":3,"names":["_components","require","_i18n","_blocks","_data","_blockEditor","_url","_coreData","_store","_lockUnlock","_jsxRuntime","PatternsManageButton","clientId","attributes","canDetach","isVisible","managePatternsUrl","isSyncedPattern","isUnsyncedPattern","useSelect","select","canRemoveBlock","getBlock","blockEditorStore","canUser","coreStore","block","_isUnsyncedPattern","window","__experimentalContentOnlyPatternInsertion","metadata","patternName","_isSyncedPattern","isReusableBlock","kind","name","id","ref","addQueryArgs","p","post_type","updateBlockAttributes","useDispatch","convertSyncedPatternToStatic","unlock","patternsStore","jsxs","Fragment","children","jsx","MenuItem","onClick","_attributes$metadata","attributesWithoutPatternName","__","href","_default","exports","default"],"sources":["@wordpress/patterns/src/components/patterns-manage-button.js"],"sourcesContent":["/**\n * WordPress dependencies\n */\nimport { MenuItem } from '@wordpress/components';\nimport { __ } from '@wordpress/i18n';\nimport { isReusableBlock } from '@wordpress/blocks';\nimport { useSelect, useDispatch } from '@wordpress/data';\nimport { store as blockEditorStore } from '@wordpress/block-editor';\nimport { addQueryArgs } from '@wordpress/url';\nimport { store as coreStore } from '@wordpress/core-data';\n\n/**\n * Internal dependencies\n */\nimport { store as patternsStore } from '../store';\nimport { unlock } from '../lock-unlock';\n\nfunction PatternsManageButton( { clientId } ) {\n\tconst {\n\t\tattributes,\n\t\tcanDetach,\n\t\tisVisible,\n\t\tmanagePatternsUrl,\n\t\tisSyncedPattern,\n\t\tisUnsyncedPattern,\n\t} = useSelect(\n\t\t( select ) => {\n\t\t\tconst { canRemoveBlock, getBlock } = select( blockEditorStore );\n\t\t\tconst { canUser } = select( coreStore );\n\t\t\tconst block = getBlock( clientId );\n\n\t\t\tconst _isUnsyncedPattern =\n\t\t\t\twindow?.__experimentalContentOnlyPatternInsertion &&\n\t\t\t\t!! block?.attributes?.metadata?.patternName;\n\n\t\t\tconst _isSyncedPattern =\n\t\t\t\t!! block &&\n\t\t\t\tisReusableBlock( block ) &&\n\t\t\t\t!! canUser( 'update', {\n\t\t\t\t\tkind: 'postType',\n\t\t\t\t\tname: 'wp_block',\n\t\t\t\t\tid: block.attributes.ref,\n\t\t\t\t} );\n\n\t\t\treturn {\n\t\t\t\tattributes: block.attributes,\n\t\t\t\t// For unsynced patterns, detaching is simply removing the `patternName` attribute.\n\t\t\t\t// For synced patterns, the `core:block` block is replaced with its inner blocks,\n\t\t\t\t// so checking whether `canRemoveBlock` is possible is required.\n\t\t\t\tcanDetach:\n\t\t\t\t\t_isUnsyncedPattern ||\n\t\t\t\t\t( _isSyncedPattern && canRemoveBlock( clientId ) ),\n\t\t\t\tisUnsyncedPattern: _isUnsyncedPattern,\n\t\t\t\tisSyncedPattern: _isSyncedPattern,\n\t\t\t\tisVisible: _isUnsyncedPattern || _isSyncedPattern,\n\t\t\t\t// The site editor and templates both check whether the user\n\t\t\t\t// has edit_theme_options capabilities. We can leverage that here\n\t\t\t\t// and omit the manage patterns link if the user can't access it.\n\t\t\t\tmanagePatternsUrl: canUser( 'create', {\n\t\t\t\t\tkind: 'postType',\n\t\t\t\t\tname: 'wp_template',\n\t\t\t\t} )\n\t\t\t\t\t? addQueryArgs( 'site-editor.php', {\n\t\t\t\t\t\t\tp: '/pattern',\n\t\t\t\t\t } )\n\t\t\t\t\t: addQueryArgs( 'edit.php', {\n\t\t\t\t\t\t\tpost_type: 'wp_block',\n\t\t\t\t\t } ),\n\t\t\t};\n\t\t},\n\t\t[ clientId ]\n\t);\n\n\tconst { updateBlockAttributes } = useDispatch( blockEditorStore );\n\n\t// Ignore reason: false positive of the lint rule.\n\t// eslint-disable-next-line @wordpress/no-unused-vars-before-return\n\tconst { convertSyncedPatternToStatic } = unlock(\n\t\tuseDispatch( patternsStore )\n\t);\n\n\tif ( ! isVisible ) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<>\n\t\t\t{ canDetach && (\n\t\t\t\t<MenuItem\n\t\t\t\t\tonClick={ () => {\n\t\t\t\t\t\tif ( isSyncedPattern ) {\n\t\t\t\t\t\t\tconvertSyncedPatternToStatic( clientId );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( isUnsyncedPattern ) {\n\t\t\t\t\t\t\tconst {\n\t\t\t\t\t\t\t\tpatternName,\n\t\t\t\t\t\t\t\t...attributesWithoutPatternName\n\t\t\t\t\t\t\t} = attributes?.metadata ?? {};\n\t\t\t\t\t\t\tupdateBlockAttributes( clientId, {\n\t\t\t\t\t\t\t\tmetadata: attributesWithoutPatternName,\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t}\n\t\t\t\t\t} }\n\t\t\t\t>\n\t\t\t\t\t{ __( 'Detach' ) }\n\t\t\t\t</MenuItem>\n\t\t\t) }\n\t\t\t<MenuItem href={ managePatternsUrl }>\n\t\t\t\t{ __( 'Manage patterns' ) }\n\t\t\t</MenuItem>\n\t\t</>\n\t);\n}\n\nexport default PatternsManageButton;\n"],"mappings":"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","ignoreList":[]}
@@ -37,7 +37,8 @@ export default function PatternConvertButton({
37
37
  createSuccessNotice
38
38
  } = useDispatch(noticesStore);
39
39
  const {
40
- replaceBlocks
40
+ replaceBlocks,
41
+ updateBlockAttributes
41
42
  } = useDispatch(blockEditorStore);
42
43
  // Ignore reason: false positive of the lint rule.
43
44
  // eslint-disable-next-line @wordpress/no-unused-vars-before-return
@@ -45,6 +46,9 @@ export default function PatternConvertButton({
45
46
  setEditingPattern
46
47
  } = unlock(useDispatch(patternsStore));
47
48
  const [isModalOpen, setIsModalOpen] = useState(false);
49
+ const {
50
+ getBlockAttributes
51
+ } = useSelect(blockEditorStore);
48
52
  const canConvert = useSelect(select => {
49
53
  var _getBlocksByClientId;
50
54
  const {
@@ -66,10 +70,11 @@ export default function PatternConvertButton({
66
70
  // If the block has a parent, check with false as default, otherwise with true.
67
71
  return hasBlockSupport(blockName, 'reusable', !hasParent);
68
72
  };
69
- const isReusable = blocks.length === 1 && blocks[0] && isReusableBlock(blocks[0]) && !!select(coreStore).getEntityRecord('postType', 'wp_block', blocks[0].attributes.ref);
73
+ const isSyncedPattern = blocks.length === 1 && blocks[0] && isReusableBlock(blocks[0]) && !!select(coreStore).getEntityRecord('postType', 'wp_block', blocks[0].attributes.ref);
74
+ const isUnsyncedPattern = window?.__experimentalContentOnlyPatternInsertion && blocks.length === 1 && blocks?.[0]?.attributes?.metadata?.patternName;
70
75
  const _canConvert =
71
- // Hide when this is already a synced pattern.
72
- !isReusable &&
76
+ // Hide when this is already a pattern.
77
+ !isUnsyncedPattern && !isSyncedPattern &&
73
78
  // Hide when patterns are disabled.
74
79
  canInsertBlockType('core/block', rootId) && blocks.every(block =>
75
80
  // Guard against the case where a regular block has *just* been converted.
@@ -96,7 +101,18 @@ export default function PatternConvertButton({
96
101
  const handleSuccess = ({
97
102
  pattern
98
103
  }) => {
99
- if (pattern.wp_pattern_sync_status !== PATTERN_SYNC_TYPES.unsynced) {
104
+ if (pattern.wp_pattern_sync_status === PATTERN_SYNC_TYPES.unsynced) {
105
+ if (clientIds?.length === 1) {
106
+ const existingAttributes = getBlockAttributes(clientIds[0]);
107
+ updateBlockAttributes(clientIds[0], {
108
+ metadata: {
109
+ ...(existingAttributes?.metadata ? existingAttributes.metadata : {}),
110
+ patternName: `core/block/${pattern.id}`,
111
+ name: pattern.title.raw
112
+ }
113
+ });
114
+ }
115
+ } else {
100
116
  const newBlock = createBlock('core/block', {
101
117
  ref: pattern.id
102
118
  });
@@ -1 +1 @@
1
- {"version":3,"names":["hasBlockSupport","isReusableBlock","createBlock","serialize","getBlockType","store","blockEditorStore","useState","useCallback","MenuItem","symbol","useSelect","useDispatch","coreStore","__","sprintf","noticesStore","patternsStore","CreatePatternModal","unlock","PATTERN_SYNC_TYPES","jsx","_jsx","Fragment","_Fragment","jsxs","_jsxs","PatternConvertButton","clientIds","rootClientId","closeBlockSettingsMenu","createSuccessNotice","replaceBlocks","setEditingPattern","isModalOpen","setIsModalOpen","canConvert","select","_getBlocksByClientId","canUser","getBlocksByClientId","canInsertBlockType","getBlockRootClientId","rootId","length","undefined","blocks","hasReusableBlockSupport","blockName","blockType","hasParent","isReusable","getEntityRecord","attributes","ref","_canConvert","every","block","isValid","name","kind","getContent","handleSuccess","pattern","wp_pattern_sync_status","unsynced","newBlock","id","clientId","title","raw","type","children","icon","onClick","content","onSuccess","onError","onClose"],"sources":["@wordpress/patterns/src/components/pattern-convert-button.js"],"sourcesContent":["/**\n * WordPress dependencies\n */\nimport {\n\thasBlockSupport,\n\tisReusableBlock,\n\tcreateBlock,\n\tserialize,\n\tgetBlockType,\n} from '@wordpress/blocks';\nimport { store as blockEditorStore } from '@wordpress/block-editor';\nimport { useState, useCallback } from '@wordpress/element';\nimport { MenuItem } from '@wordpress/components';\nimport { symbol } from '@wordpress/icons';\nimport { useSelect, useDispatch } from '@wordpress/data';\nimport { store as coreStore } from '@wordpress/core-data';\nimport { __, sprintf } from '@wordpress/i18n';\nimport { store as noticesStore } from '@wordpress/notices';\n/**\n * Internal dependencies\n */\nimport { store as patternsStore } from '../store';\nimport CreatePatternModal from './create-pattern-modal';\nimport { unlock } from '../lock-unlock';\nimport { PATTERN_SYNC_TYPES } from '../constants';\n\n/**\n * Menu control to convert block(s) to a pattern block.\n *\n * @param {Object} props Component props.\n * @param {string[]} props.clientIds Client ids of selected blocks.\n * @param {string} props.rootClientId ID of the currently selected top-level block.\n * @param {()=>void} props.closeBlockSettingsMenu Callback to close the block settings menu dropdown.\n * @return {import('react').ComponentType} The menu control or null.\n */\nexport default function PatternConvertButton( {\n\tclientIds,\n\trootClientId,\n\tcloseBlockSettingsMenu,\n} ) {\n\tconst { createSuccessNotice } = useDispatch( noticesStore );\n\tconst { replaceBlocks } = useDispatch( blockEditorStore );\n\t// Ignore reason: false positive of the lint rule.\n\t// eslint-disable-next-line @wordpress/no-unused-vars-before-return\n\tconst { setEditingPattern } = unlock( useDispatch( patternsStore ) );\n\tconst [ isModalOpen, setIsModalOpen ] = useState( false );\n\tconst canConvert = useSelect(\n\t\t( select ) => {\n\t\t\tconst { canUser } = select( coreStore );\n\t\t\tconst {\n\t\t\t\tgetBlocksByClientId,\n\t\t\t\tcanInsertBlockType,\n\t\t\t\tgetBlockRootClientId,\n\t\t\t} = select( blockEditorStore );\n\n\t\t\tconst rootId =\n\t\t\t\trootClientId ||\n\t\t\t\t( clientIds.length > 0\n\t\t\t\t\t? getBlockRootClientId( clientIds[ 0 ] )\n\t\t\t\t\t: undefined );\n\n\t\t\tconst blocks = getBlocksByClientId( clientIds ) ?? [];\n\n\t\t\t// Check if the block has reusable support defined.\n\t\t\tconst hasReusableBlockSupport = ( blockName ) => {\n\t\t\t\tconst blockType = getBlockType( blockName );\n\t\t\t\tconst hasParent = blockType && 'parent' in blockType;\n\n\t\t\t\t// If the block has a parent, check with false as default, otherwise with true.\n\t\t\t\treturn hasBlockSupport( blockName, 'reusable', ! hasParent );\n\t\t\t};\n\n\t\t\tconst isReusable =\n\t\t\t\tblocks.length === 1 &&\n\t\t\t\tblocks[ 0 ] &&\n\t\t\t\tisReusableBlock( blocks[ 0 ] ) &&\n\t\t\t\t!! select( coreStore ).getEntityRecord(\n\t\t\t\t\t'postType',\n\t\t\t\t\t'wp_block',\n\t\t\t\t\tblocks[ 0 ].attributes.ref\n\t\t\t\t);\n\n\t\t\tconst _canConvert =\n\t\t\t\t// Hide when this is already a synced pattern.\n\t\t\t\t! isReusable &&\n\t\t\t\t// Hide when patterns are disabled.\n\t\t\t\tcanInsertBlockType( 'core/block', rootId ) &&\n\t\t\t\tblocks.every(\n\t\t\t\t\t( block ) =>\n\t\t\t\t\t\t// Guard against the case where a regular block has *just* been converted.\n\t\t\t\t\t\t!! block &&\n\t\t\t\t\t\t// Hide on invalid blocks.\n\t\t\t\t\t\tblock.isValid &&\n\t\t\t\t\t\t// Hide when block doesn't support being made into a pattern.\n\t\t\t\t\t\thasReusableBlockSupport( block.name )\n\t\t\t\t) &&\n\t\t\t\t// Hide when current doesn't have permission to do that.\n\t\t\t\t// Blocks refers to the wp_block post type, this checks the ability to create a post of that type.\n\t\t\t\t!! canUser( 'create', {\n\t\t\t\t\tkind: 'postType',\n\t\t\t\t\tname: 'wp_block',\n\t\t\t\t} );\n\n\t\t\treturn _canConvert;\n\t\t},\n\t\t[ clientIds, rootClientId ]\n\t);\n\tconst { getBlocksByClientId } = useSelect( blockEditorStore );\n\tconst getContent = useCallback(\n\t\t() => serialize( getBlocksByClientId( clientIds ) ),\n\t\t[ getBlocksByClientId, clientIds ]\n\t);\n\n\tif ( ! canConvert ) {\n\t\treturn null;\n\t}\n\n\tconst handleSuccess = ( { pattern } ) => {\n\t\tif ( pattern.wp_pattern_sync_status !== PATTERN_SYNC_TYPES.unsynced ) {\n\t\t\tconst newBlock = createBlock( 'core/block', {\n\t\t\t\tref: pattern.id,\n\t\t\t} );\n\n\t\t\treplaceBlocks( clientIds, newBlock );\n\t\t\tsetEditingPattern( newBlock.clientId, true );\n\t\t\tcloseBlockSettingsMenu();\n\t\t}\n\n\t\tcreateSuccessNotice(\n\t\t\tpattern.wp_pattern_sync_status === PATTERN_SYNC_TYPES.unsynced\n\t\t\t\t? sprintf(\n\t\t\t\t\t\t// translators: %s: the name the user has given to the pattern.\n\t\t\t\t\t\t__( 'Unsynced pattern created: %s' ),\n\t\t\t\t\t\tpattern.title.raw\n\t\t\t\t )\n\t\t\t\t: sprintf(\n\t\t\t\t\t\t// translators: %s: the name the user has given to the pattern.\n\t\t\t\t\t\t__( 'Synced pattern created: %s' ),\n\t\t\t\t\t\tpattern.title.raw\n\t\t\t\t ),\n\t\t\t{\n\t\t\t\ttype: 'snackbar',\n\t\t\t\tid: 'convert-to-pattern-success',\n\t\t\t}\n\t\t);\n\t\tsetIsModalOpen( false );\n\t};\n\treturn (\n\t\t<>\n\t\t\t<MenuItem\n\t\t\t\ticon={ symbol }\n\t\t\t\tonClick={ () => setIsModalOpen( true ) }\n\t\t\t\taria-expanded={ isModalOpen }\n\t\t\t\taria-haspopup=\"dialog\"\n\t\t\t>\n\t\t\t\t{ __( 'Create pattern' ) }\n\t\t\t</MenuItem>\n\t\t\t{ isModalOpen && (\n\t\t\t\t<CreatePatternModal\n\t\t\t\t\tcontent={ getContent }\n\t\t\t\t\tonSuccess={ ( pattern ) => {\n\t\t\t\t\t\thandleSuccess( pattern );\n\t\t\t\t\t} }\n\t\t\t\t\tonError={ () => {\n\t\t\t\t\t\tsetIsModalOpen( false );\n\t\t\t\t\t} }\n\t\t\t\t\tonClose={ () => {\n\t\t\t\t\t\tsetIsModalOpen( false );\n\t\t\t\t\t} }\n\t\t\t\t/>\n\t\t\t) }\n\t\t</>\n\t);\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["hasBlockSupport","isReusableBlock","createBlock","serialize","getBlockType","store","blockEditorStore","useState","useCallback","MenuItem","symbol","useSelect","useDispatch","coreStore","__","sprintf","noticesStore","patternsStore","CreatePatternModal","unlock","PATTERN_SYNC_TYPES","jsx","_jsx","Fragment","_Fragment","jsxs","_jsxs","PatternConvertButton","clientIds","rootClientId","closeBlockSettingsMenu","createSuccessNotice","replaceBlocks","updateBlockAttributes","setEditingPattern","isModalOpen","setIsModalOpen","getBlockAttributes","canConvert","select","_getBlocksByClientId","canUser","getBlocksByClientId","canInsertBlockType","getBlockRootClientId","rootId","length","undefined","blocks","hasReusableBlockSupport","blockName","blockType","hasParent","isSyncedPattern","getEntityRecord","attributes","ref","isUnsyncedPattern","window","__experimentalContentOnlyPatternInsertion","metadata","patternName","_canConvert","every","block","isValid","name","kind","getContent","handleSuccess","pattern","wp_pattern_sync_status","unsynced","existingAttributes","id","title","raw","newBlock","clientId","type","children","icon","onClick","content","onSuccess","onError","onClose"],"sources":["@wordpress/patterns/src/components/pattern-convert-button.js"],"sourcesContent":["/**\n * WordPress dependencies\n */\nimport {\n\thasBlockSupport,\n\tisReusableBlock,\n\tcreateBlock,\n\tserialize,\n\tgetBlockType,\n} from '@wordpress/blocks';\nimport { store as blockEditorStore } from '@wordpress/block-editor';\nimport { useState, useCallback } from '@wordpress/element';\nimport { MenuItem } from '@wordpress/components';\nimport { symbol } from '@wordpress/icons';\nimport { useSelect, useDispatch } from '@wordpress/data';\nimport { store as coreStore } from '@wordpress/core-data';\nimport { __, sprintf } from '@wordpress/i18n';\nimport { store as noticesStore } from '@wordpress/notices';\n/**\n * Internal dependencies\n */\nimport { store as patternsStore } from '../store';\nimport CreatePatternModal from './create-pattern-modal';\nimport { unlock } from '../lock-unlock';\nimport { PATTERN_SYNC_TYPES } from '../constants';\n\n/**\n * Menu control to convert block(s) to a pattern block.\n *\n * @param {Object} props Component props.\n * @param {string[]} props.clientIds Client ids of selected blocks.\n * @param {string} props.rootClientId ID of the currently selected top-level block.\n * @param {()=>void} props.closeBlockSettingsMenu Callback to close the block settings menu dropdown.\n * @return {import('react').ComponentType} The menu control or null.\n */\nexport default function PatternConvertButton( {\n\tclientIds,\n\trootClientId,\n\tcloseBlockSettingsMenu,\n} ) {\n\tconst { createSuccessNotice } = useDispatch( noticesStore );\n\tconst { replaceBlocks, updateBlockAttributes } =\n\t\tuseDispatch( blockEditorStore );\n\t// Ignore reason: false positive of the lint rule.\n\t// eslint-disable-next-line @wordpress/no-unused-vars-before-return\n\tconst { setEditingPattern } = unlock( useDispatch( patternsStore ) );\n\tconst [ isModalOpen, setIsModalOpen ] = useState( false );\n\tconst { getBlockAttributes } = useSelect( blockEditorStore );\n\tconst canConvert = useSelect(\n\t\t( select ) => {\n\t\t\tconst { canUser } = select( coreStore );\n\t\t\tconst {\n\t\t\t\tgetBlocksByClientId,\n\t\t\t\tcanInsertBlockType,\n\t\t\t\tgetBlockRootClientId,\n\t\t\t} = select( blockEditorStore );\n\n\t\t\tconst rootId =\n\t\t\t\trootClientId ||\n\t\t\t\t( clientIds.length > 0\n\t\t\t\t\t? getBlockRootClientId( clientIds[ 0 ] )\n\t\t\t\t\t: undefined );\n\n\t\t\tconst blocks = getBlocksByClientId( clientIds ) ?? [];\n\n\t\t\t// Check if the block has reusable support defined.\n\t\t\tconst hasReusableBlockSupport = ( blockName ) => {\n\t\t\t\tconst blockType = getBlockType( blockName );\n\t\t\t\tconst hasParent = blockType && 'parent' in blockType;\n\n\t\t\t\t// If the block has a parent, check with false as default, otherwise with true.\n\t\t\t\treturn hasBlockSupport( blockName, 'reusable', ! hasParent );\n\t\t\t};\n\n\t\t\tconst isSyncedPattern =\n\t\t\t\tblocks.length === 1 &&\n\t\t\t\tblocks[ 0 ] &&\n\t\t\t\tisReusableBlock( blocks[ 0 ] ) &&\n\t\t\t\t!! select( coreStore ).getEntityRecord(\n\t\t\t\t\t'postType',\n\t\t\t\t\t'wp_block',\n\t\t\t\t\tblocks[ 0 ].attributes.ref\n\t\t\t\t);\n\n\t\t\tconst isUnsyncedPattern =\n\t\t\t\twindow?.__experimentalContentOnlyPatternInsertion &&\n\t\t\t\tblocks.length === 1 &&\n\t\t\t\tblocks?.[ 0 ]?.attributes?.metadata?.patternName;\n\n\t\t\tconst _canConvert =\n\t\t\t\t// Hide when this is already a pattern.\n\t\t\t\t! isUnsyncedPattern &&\n\t\t\t\t! isSyncedPattern &&\n\t\t\t\t// Hide when patterns are disabled.\n\t\t\t\tcanInsertBlockType( 'core/block', rootId ) &&\n\t\t\t\tblocks.every(\n\t\t\t\t\t( block ) =>\n\t\t\t\t\t\t// Guard against the case where a regular block has *just* been converted.\n\t\t\t\t\t\t!! block &&\n\t\t\t\t\t\t// Hide on invalid blocks.\n\t\t\t\t\t\tblock.isValid &&\n\t\t\t\t\t\t// Hide when block doesn't support being made into a pattern.\n\t\t\t\t\t\thasReusableBlockSupport( block.name )\n\t\t\t\t) &&\n\t\t\t\t// Hide when current doesn't have permission to do that.\n\t\t\t\t// Blocks refers to the wp_block post type, this checks the ability to create a post of that type.\n\t\t\t\t!! canUser( 'create', {\n\t\t\t\t\tkind: 'postType',\n\t\t\t\t\tname: 'wp_block',\n\t\t\t\t} );\n\n\t\t\treturn _canConvert;\n\t\t},\n\t\t[ clientIds, rootClientId ]\n\t);\n\tconst { getBlocksByClientId } = useSelect( blockEditorStore );\n\tconst getContent = useCallback(\n\t\t() => serialize( getBlocksByClientId( clientIds ) ),\n\t\t[ getBlocksByClientId, clientIds ]\n\t);\n\n\tif ( ! canConvert ) {\n\t\treturn null;\n\t}\n\n\tconst handleSuccess = ( { pattern } ) => {\n\t\tif ( pattern.wp_pattern_sync_status === PATTERN_SYNC_TYPES.unsynced ) {\n\t\t\tif ( clientIds?.length === 1 ) {\n\t\t\t\tconst existingAttributes = getBlockAttributes( clientIds[ 0 ] );\n\t\t\t\tupdateBlockAttributes( clientIds[ 0 ], {\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\t...( existingAttributes?.metadata\n\t\t\t\t\t\t\t? existingAttributes.metadata\n\t\t\t\t\t\t\t: {} ),\n\t\t\t\t\t\tpatternName: `core/block/${ pattern.id }`,\n\t\t\t\t\t\tname: pattern.title.raw,\n\t\t\t\t\t},\n\t\t\t\t} );\n\t\t\t}\n\t\t} else {\n\t\t\tconst newBlock = createBlock( 'core/block', {\n\t\t\t\tref: pattern.id,\n\t\t\t} );\n\n\t\t\treplaceBlocks( clientIds, newBlock );\n\t\t\tsetEditingPattern( newBlock.clientId, true );\n\t\t\tcloseBlockSettingsMenu();\n\t\t}\n\n\t\tcreateSuccessNotice(\n\t\t\tpattern.wp_pattern_sync_status === PATTERN_SYNC_TYPES.unsynced\n\t\t\t\t? sprintf(\n\t\t\t\t\t\t// translators: %s: the name the user has given to the pattern.\n\t\t\t\t\t\t__( 'Unsynced pattern created: %s' ),\n\t\t\t\t\t\tpattern.title.raw\n\t\t\t\t )\n\t\t\t\t: sprintf(\n\t\t\t\t\t\t// translators: %s: the name the user has given to the pattern.\n\t\t\t\t\t\t__( 'Synced pattern created: %s' ),\n\t\t\t\t\t\tpattern.title.raw\n\t\t\t\t ),\n\t\t\t{\n\t\t\t\ttype: 'snackbar',\n\t\t\t\tid: 'convert-to-pattern-success',\n\t\t\t}\n\t\t);\n\t\tsetIsModalOpen( false );\n\t};\n\treturn (\n\t\t<>\n\t\t\t<MenuItem\n\t\t\t\ticon={ symbol }\n\t\t\t\tonClick={ () => setIsModalOpen( true ) }\n\t\t\t\taria-expanded={ isModalOpen }\n\t\t\t\taria-haspopup=\"dialog\"\n\t\t\t>\n\t\t\t\t{ __( 'Create pattern' ) }\n\t\t\t</MenuItem>\n\t\t\t{ isModalOpen && (\n\t\t\t\t<CreatePatternModal\n\t\t\t\t\tcontent={ getContent }\n\t\t\t\t\tonSuccess={ ( pattern ) => {\n\t\t\t\t\t\thandleSuccess( pattern );\n\t\t\t\t\t} }\n\t\t\t\t\tonError={ () => {\n\t\t\t\t\t\tsetIsModalOpen( false );\n\t\t\t\t\t} }\n\t\t\t\t\tonClose={ () => {\n\t\t\t\t\t\tsetIsModalOpen( false );\n\t\t\t\t\t} }\n\t\t\t\t/>\n\t\t\t) }\n\t\t</>\n\t);\n}\n"],"mappings":"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","ignoreList":[]}
@@ -19,25 +19,36 @@ function PatternsManageButton({
19
19
  clientId
20
20
  }) {
21
21
  const {
22
- canRemove,
22
+ attributes,
23
+ canDetach,
23
24
  isVisible,
24
- managePatternsUrl
25
+ managePatternsUrl,
26
+ isSyncedPattern,
27
+ isUnsyncedPattern
25
28
  } = useSelect(select => {
26
29
  const {
27
- getBlock,
28
- canRemoveBlock
30
+ canRemoveBlock,
31
+ getBlock
29
32
  } = select(blockEditorStore);
30
33
  const {
31
34
  canUser
32
35
  } = select(coreStore);
33
- const reusableBlock = getBlock(clientId);
36
+ const block = getBlock(clientId);
37
+ const _isUnsyncedPattern = window?.__experimentalContentOnlyPatternInsertion && !!block?.attributes?.metadata?.patternName;
38
+ const _isSyncedPattern = !!block && isReusableBlock(block) && !!canUser('update', {
39
+ kind: 'postType',
40
+ name: 'wp_block',
41
+ id: block.attributes.ref
42
+ });
34
43
  return {
35
- canRemove: canRemoveBlock(clientId),
36
- isVisible: !!reusableBlock && isReusableBlock(reusableBlock) && !!canUser('update', {
37
- kind: 'postType',
38
- name: 'wp_block',
39
- id: reusableBlock.attributes.ref
40
- }),
44
+ attributes: block.attributes,
45
+ // For unsynced patterns, detaching is simply removing the `patternName` attribute.
46
+ // For synced patterns, the `core:block` block is replaced with its inner blocks,
47
+ // so checking whether `canRemoveBlock` is possible is required.
48
+ canDetach: _isUnsyncedPattern || _isSyncedPattern && canRemoveBlock(clientId),
49
+ isUnsyncedPattern: _isUnsyncedPattern,
50
+ isSyncedPattern: _isSyncedPattern,
51
+ isVisible: _isUnsyncedPattern || _isSyncedPattern,
41
52
  // The site editor and templates both check whether the user
42
53
  // has edit_theme_options capabilities. We can leverage that here
43
54
  // and omit the manage patterns link if the user can't access it.
@@ -51,6 +62,9 @@ function PatternsManageButton({
51
62
  })
52
63
  };
53
64
  }, [clientId]);
65
+ const {
66
+ updateBlockAttributes
67
+ } = useDispatch(blockEditorStore);
54
68
 
55
69
  // Ignore reason: false positive of the lint rule.
56
70
  // eslint-disable-next-line @wordpress/no-unused-vars-before-return
@@ -61,8 +75,22 @@ function PatternsManageButton({
61
75
  return null;
62
76
  }
63
77
  return /*#__PURE__*/_jsxs(_Fragment, {
64
- children: [canRemove && /*#__PURE__*/_jsx(MenuItem, {
65
- onClick: () => convertSyncedPatternToStatic(clientId),
78
+ children: [canDetach && /*#__PURE__*/_jsx(MenuItem, {
79
+ onClick: () => {
80
+ if (isSyncedPattern) {
81
+ convertSyncedPatternToStatic(clientId);
82
+ }
83
+ if (isUnsyncedPattern) {
84
+ var _attributes$metadata;
85
+ const {
86
+ patternName,
87
+ ...attributesWithoutPatternName
88
+ } = (_attributes$metadata = attributes?.metadata) !== null && _attributes$metadata !== void 0 ? _attributes$metadata : {};
89
+ updateBlockAttributes(clientId, {
90
+ metadata: attributesWithoutPatternName
91
+ });
92
+ }
93
+ },
66
94
  children: __('Detach')
67
95
  }), /*#__PURE__*/_jsx(MenuItem, {
68
96
  href: managePatternsUrl,
@@ -1 +1 @@
1
- {"version":3,"names":["MenuItem","__","isReusableBlock","useSelect","useDispatch","store","blockEditorStore","addQueryArgs","coreStore","patternsStore","unlock","jsx","_jsx","Fragment","_Fragment","jsxs","_jsxs","PatternsManageButton","clientId","canRemove","isVisible","managePatternsUrl","select","getBlock","canRemoveBlock","canUser","reusableBlock","kind","name","id","attributes","ref","p","post_type","convertSyncedPatternToStatic","children","onClick","href"],"sources":["@wordpress/patterns/src/components/patterns-manage-button.js"],"sourcesContent":["/**\n * WordPress dependencies\n */\nimport { MenuItem } from '@wordpress/components';\nimport { __ } from '@wordpress/i18n';\nimport { isReusableBlock } from '@wordpress/blocks';\nimport { useSelect, useDispatch } from '@wordpress/data';\nimport { store as blockEditorStore } from '@wordpress/block-editor';\nimport { addQueryArgs } from '@wordpress/url';\nimport { store as coreStore } from '@wordpress/core-data';\n\n/**\n * Internal dependencies\n */\nimport { store as patternsStore } from '../store';\nimport { unlock } from '../lock-unlock';\n\nfunction PatternsManageButton( { clientId } ) {\n\tconst { canRemove, isVisible, managePatternsUrl } = useSelect(\n\t\t( select ) => {\n\t\t\tconst { getBlock, canRemoveBlock } = select( blockEditorStore );\n\t\t\tconst { canUser } = select( coreStore );\n\t\t\tconst reusableBlock = getBlock( clientId );\n\n\t\t\treturn {\n\t\t\t\tcanRemove: canRemoveBlock( clientId ),\n\t\t\t\tisVisible:\n\t\t\t\t\t!! reusableBlock &&\n\t\t\t\t\tisReusableBlock( reusableBlock ) &&\n\t\t\t\t\t!! canUser( 'update', {\n\t\t\t\t\t\tkind: 'postType',\n\t\t\t\t\t\tname: 'wp_block',\n\t\t\t\t\t\tid: reusableBlock.attributes.ref,\n\t\t\t\t\t} ),\n\t\t\t\t// The site editor and templates both check whether the user\n\t\t\t\t// has edit_theme_options capabilities. We can leverage that here\n\t\t\t\t// and omit the manage patterns link if the user can't access it.\n\t\t\t\tmanagePatternsUrl: canUser( 'create', {\n\t\t\t\t\tkind: 'postType',\n\t\t\t\t\tname: 'wp_template',\n\t\t\t\t} )\n\t\t\t\t\t? addQueryArgs( 'site-editor.php', {\n\t\t\t\t\t\t\tp: '/pattern',\n\t\t\t\t\t } )\n\t\t\t\t\t: addQueryArgs( 'edit.php', {\n\t\t\t\t\t\t\tpost_type: 'wp_block',\n\t\t\t\t\t } ),\n\t\t\t};\n\t\t},\n\t\t[ clientId ]\n\t);\n\n\t// Ignore reason: false positive of the lint rule.\n\t// eslint-disable-next-line @wordpress/no-unused-vars-before-return\n\tconst { convertSyncedPatternToStatic } = unlock(\n\t\tuseDispatch( patternsStore )\n\t);\n\n\tif ( ! isVisible ) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<>\n\t\t\t{ canRemove && (\n\t\t\t\t<MenuItem\n\t\t\t\t\tonClick={ () => convertSyncedPatternToStatic( clientId ) }\n\t\t\t\t>\n\t\t\t\t\t{ __( 'Detach' ) }\n\t\t\t\t</MenuItem>\n\t\t\t) }\n\t\t\t<MenuItem href={ managePatternsUrl }>\n\t\t\t\t{ __( 'Manage patterns' ) }\n\t\t\t</MenuItem>\n\t\t</>\n\t);\n}\n\nexport default PatternsManageButton;\n"],"mappings":"AAAA;AACA;AACA;AACA,SAASA,QAAQ,QAAQ,uBAAuB;AAChD,SAASC,EAAE,QAAQ,iBAAiB;AACpC,SAASC,eAAe,QAAQ,mBAAmB;AACnD,SAASC,SAAS,EAAEC,WAAW,QAAQ,iBAAiB;AACxD,SAASC,KAAK,IAAIC,gBAAgB,QAAQ,yBAAyB;AACnE,SAASC,YAAY,QAAQ,gBAAgB;AAC7C,SAASF,KAAK,IAAIG,SAAS,QAAQ,sBAAsB;;AAEzD;AACA;AACA;AACA,SAASH,KAAK,IAAII,aAAa,QAAQ,UAAU;AACjD,SAASC,MAAM,QAAQ,gBAAgB;AAAC,SAAAC,GAAA,IAAAC,IAAA,EAAAC,QAAA,IAAAC,SAAA,EAAAC,IAAA,IAAAC,KAAA;AAExC,SAASC,oBAAoBA,CAAE;EAAEC;AAAS,CAAC,EAAG;EAC7C,MAAM;IAAEC,SAAS;IAAEC,SAAS;IAAEC;EAAkB,CAAC,GAAGlB,SAAS,CAC1DmB,MAAM,IAAM;IACb,MAAM;MAAEC,QAAQ;MAAEC;IAAe,CAAC,GAAGF,MAAM,CAAEhB,gBAAiB,CAAC;IAC/D,MAAM;MAAEmB;IAAQ,CAAC,GAAGH,MAAM,CAAEd,SAAU,CAAC;IACvC,MAAMkB,aAAa,GAAGH,QAAQ,CAAEL,QAAS,CAAC;IAE1C,OAAO;MACNC,SAAS,EAAEK,cAAc,CAAEN,QAAS,CAAC;MACrCE,SAAS,EACR,CAAC,CAAEM,aAAa,IAChBxB,eAAe,CAAEwB,aAAc,CAAC,IAChC,CAAC,CAAED,OAAO,CAAE,QAAQ,EAAE;QACrBE,IAAI,EAAE,UAAU;QAChBC,IAAI,EAAE,UAAU;QAChBC,EAAE,EAAEH,aAAa,CAACI,UAAU,CAACC;MAC9B,CAAE,CAAC;MACJ;MACA;MACA;MACAV,iBAAiB,EAAEI,OAAO,CAAE,QAAQ,EAAE;QACrCE,IAAI,EAAE,UAAU;QAChBC,IAAI,EAAE;MACP,CAAE,CAAC,GACArB,YAAY,CAAE,iBAAiB,EAAE;QACjCyB,CAAC,EAAE;MACH,CAAE,CAAC,GACHzB,YAAY,CAAE,UAAU,EAAE;QAC1B0B,SAAS,EAAE;MACX,CAAE;IACN,CAAC;EACF,CAAC,EACD,CAAEf,QAAQ,CACX,CAAC;;EAED;EACA;EACA,MAAM;IAAEgB;EAA6B,CAAC,GAAGxB,MAAM,CAC9CN,WAAW,CAAEK,aAAc,CAC5B,CAAC;EAED,IAAK,CAAEW,SAAS,EAAG;IAClB,OAAO,IAAI;EACZ;EAEA,oBACCJ,KAAA,CAAAF,SAAA;IAAAqB,QAAA,GACGhB,SAAS,iBACVP,IAAA,CAACZ,QAAQ;MACRoC,OAAO,EAAGA,CAAA,KAAMF,4BAA4B,CAAEhB,QAAS,CAAG;MAAAiB,QAAA,EAExDlC,EAAE,CAAE,QAAS;IAAC,CACP,CACV,eACDW,IAAA,CAACZ,QAAQ;MAACqC,IAAI,EAAGhB,iBAAmB;MAAAc,QAAA,EACjClC,EAAE,CAAE,iBAAkB;IAAC,CAChB,CAAC;EAAA,CACV,CAAC;AAEL;AAEA,eAAegB,oBAAoB","ignoreList":[]}
1
+ {"version":3,"names":["MenuItem","__","isReusableBlock","useSelect","useDispatch","store","blockEditorStore","addQueryArgs","coreStore","patternsStore","unlock","jsx","_jsx","Fragment","_Fragment","jsxs","_jsxs","PatternsManageButton","clientId","attributes","canDetach","isVisible","managePatternsUrl","isSyncedPattern","isUnsyncedPattern","select","canRemoveBlock","getBlock","canUser","block","_isUnsyncedPattern","window","__experimentalContentOnlyPatternInsertion","metadata","patternName","_isSyncedPattern","kind","name","id","ref","p","post_type","updateBlockAttributes","convertSyncedPatternToStatic","children","onClick","_attributes$metadata","attributesWithoutPatternName","href"],"sources":["@wordpress/patterns/src/components/patterns-manage-button.js"],"sourcesContent":["/**\n * WordPress dependencies\n */\nimport { MenuItem } from '@wordpress/components';\nimport { __ } from '@wordpress/i18n';\nimport { isReusableBlock } from '@wordpress/blocks';\nimport { useSelect, useDispatch } from '@wordpress/data';\nimport { store as blockEditorStore } from '@wordpress/block-editor';\nimport { addQueryArgs } from '@wordpress/url';\nimport { store as coreStore } from '@wordpress/core-data';\n\n/**\n * Internal dependencies\n */\nimport { store as patternsStore } from '../store';\nimport { unlock } from '../lock-unlock';\n\nfunction PatternsManageButton( { clientId } ) {\n\tconst {\n\t\tattributes,\n\t\tcanDetach,\n\t\tisVisible,\n\t\tmanagePatternsUrl,\n\t\tisSyncedPattern,\n\t\tisUnsyncedPattern,\n\t} = useSelect(\n\t\t( select ) => {\n\t\t\tconst { canRemoveBlock, getBlock } = select( blockEditorStore );\n\t\t\tconst { canUser } = select( coreStore );\n\t\t\tconst block = getBlock( clientId );\n\n\t\t\tconst _isUnsyncedPattern =\n\t\t\t\twindow?.__experimentalContentOnlyPatternInsertion &&\n\t\t\t\t!! block?.attributes?.metadata?.patternName;\n\n\t\t\tconst _isSyncedPattern =\n\t\t\t\t!! block &&\n\t\t\t\tisReusableBlock( block ) &&\n\t\t\t\t!! canUser( 'update', {\n\t\t\t\t\tkind: 'postType',\n\t\t\t\t\tname: 'wp_block',\n\t\t\t\t\tid: block.attributes.ref,\n\t\t\t\t} );\n\n\t\t\treturn {\n\t\t\t\tattributes: block.attributes,\n\t\t\t\t// For unsynced patterns, detaching is simply removing the `patternName` attribute.\n\t\t\t\t// For synced patterns, the `core:block` block is replaced with its inner blocks,\n\t\t\t\t// so checking whether `canRemoveBlock` is possible is required.\n\t\t\t\tcanDetach:\n\t\t\t\t\t_isUnsyncedPattern ||\n\t\t\t\t\t( _isSyncedPattern && canRemoveBlock( clientId ) ),\n\t\t\t\tisUnsyncedPattern: _isUnsyncedPattern,\n\t\t\t\tisSyncedPattern: _isSyncedPattern,\n\t\t\t\tisVisible: _isUnsyncedPattern || _isSyncedPattern,\n\t\t\t\t// The site editor and templates both check whether the user\n\t\t\t\t// has edit_theme_options capabilities. We can leverage that here\n\t\t\t\t// and omit the manage patterns link if the user can't access it.\n\t\t\t\tmanagePatternsUrl: canUser( 'create', {\n\t\t\t\t\tkind: 'postType',\n\t\t\t\t\tname: 'wp_template',\n\t\t\t\t} )\n\t\t\t\t\t? addQueryArgs( 'site-editor.php', {\n\t\t\t\t\t\t\tp: '/pattern',\n\t\t\t\t\t } )\n\t\t\t\t\t: addQueryArgs( 'edit.php', {\n\t\t\t\t\t\t\tpost_type: 'wp_block',\n\t\t\t\t\t } ),\n\t\t\t};\n\t\t},\n\t\t[ clientId ]\n\t);\n\n\tconst { updateBlockAttributes } = useDispatch( blockEditorStore );\n\n\t// Ignore reason: false positive of the lint rule.\n\t// eslint-disable-next-line @wordpress/no-unused-vars-before-return\n\tconst { convertSyncedPatternToStatic } = unlock(\n\t\tuseDispatch( patternsStore )\n\t);\n\n\tif ( ! isVisible ) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<>\n\t\t\t{ canDetach && (\n\t\t\t\t<MenuItem\n\t\t\t\t\tonClick={ () => {\n\t\t\t\t\t\tif ( isSyncedPattern ) {\n\t\t\t\t\t\t\tconvertSyncedPatternToStatic( clientId );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( isUnsyncedPattern ) {\n\t\t\t\t\t\t\tconst {\n\t\t\t\t\t\t\t\tpatternName,\n\t\t\t\t\t\t\t\t...attributesWithoutPatternName\n\t\t\t\t\t\t\t} = attributes?.metadata ?? {};\n\t\t\t\t\t\t\tupdateBlockAttributes( clientId, {\n\t\t\t\t\t\t\t\tmetadata: attributesWithoutPatternName,\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t}\n\t\t\t\t\t} }\n\t\t\t\t>\n\t\t\t\t\t{ __( 'Detach' ) }\n\t\t\t\t</MenuItem>\n\t\t\t) }\n\t\t\t<MenuItem href={ managePatternsUrl }>\n\t\t\t\t{ __( 'Manage patterns' ) }\n\t\t\t</MenuItem>\n\t\t</>\n\t);\n}\n\nexport default PatternsManageButton;\n"],"mappings":"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","ignoreList":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/patterns",
3
- "version": "2.30.1-next.836ecdcae.0",
3
+ "version": "2.31.0",
4
4
  "description": "Management of user pattern editing.",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -33,20 +33,20 @@
33
33
  ],
34
34
  "dependencies": {
35
35
  "@babel/runtime": "7.25.7",
36
- "@wordpress/a11y": "^4.30.1-next.836ecdcae.0",
37
- "@wordpress/block-editor": "^15.3.1-next.836ecdcae.0",
38
- "@wordpress/blocks": "^15.3.1-next.836ecdcae.0",
39
- "@wordpress/components": "^30.3.2-next.836ecdcae.0",
40
- "@wordpress/compose": "^7.30.1-next.836ecdcae.0",
41
- "@wordpress/core-data": "^7.30.1-next.836ecdcae.0",
42
- "@wordpress/data": "^10.30.1-next.836ecdcae.0",
43
- "@wordpress/element": "^6.30.1-next.836ecdcae.0",
44
- "@wordpress/html-entities": "^4.30.1-next.836ecdcae.0",
45
- "@wordpress/i18n": "^6.3.1-next.836ecdcae.0",
46
- "@wordpress/icons": "^10.30.1-next.836ecdcae.0",
47
- "@wordpress/notices": "^5.30.1-next.836ecdcae.0",
48
- "@wordpress/private-apis": "^1.30.1-next.836ecdcae.0",
49
- "@wordpress/url": "^4.30.1-next.836ecdcae.0"
36
+ "@wordpress/a11y": "^4.31.0",
37
+ "@wordpress/block-editor": "^15.4.0",
38
+ "@wordpress/blocks": "^15.4.0",
39
+ "@wordpress/components": "^30.4.0",
40
+ "@wordpress/compose": "^7.31.0",
41
+ "@wordpress/core-data": "^7.31.0",
42
+ "@wordpress/data": "^10.31.0",
43
+ "@wordpress/element": "^6.31.0",
44
+ "@wordpress/html-entities": "^4.31.0",
45
+ "@wordpress/i18n": "^6.4.0",
46
+ "@wordpress/icons": "^10.31.0",
47
+ "@wordpress/notices": "^5.31.0",
48
+ "@wordpress/private-apis": "^1.31.0",
49
+ "@wordpress/url": "^4.31.0"
50
50
  },
51
51
  "peerDependencies": {
52
52
  "react": "^18.0.0",
@@ -55,5 +55,5 @@
55
55
  "publishConfig": {
56
56
  "access": "public"
57
57
  },
58
- "gitHead": "3e60b4c1e78d7b27acbf1d7dd172bbd64358a0f2"
58
+ "gitHead": "d7601d30d49462ea942168e8ab6bf449fb93097e"
59
59
  }
@@ -39,11 +39,13 @@ export default function PatternConvertButton( {
39
39
  closeBlockSettingsMenu,
40
40
  } ) {
41
41
  const { createSuccessNotice } = useDispatch( noticesStore );
42
- const { replaceBlocks } = useDispatch( blockEditorStore );
42
+ const { replaceBlocks, updateBlockAttributes } =
43
+ useDispatch( blockEditorStore );
43
44
  // Ignore reason: false positive of the lint rule.
44
45
  // eslint-disable-next-line @wordpress/no-unused-vars-before-return
45
46
  const { setEditingPattern } = unlock( useDispatch( patternsStore ) );
46
47
  const [ isModalOpen, setIsModalOpen ] = useState( false );
48
+ const { getBlockAttributes } = useSelect( blockEditorStore );
47
49
  const canConvert = useSelect(
48
50
  ( select ) => {
49
51
  const { canUser } = select( coreStore );
@@ -70,7 +72,7 @@ export default function PatternConvertButton( {
70
72
  return hasBlockSupport( blockName, 'reusable', ! hasParent );
71
73
  };
72
74
 
73
- const isReusable =
75
+ const isSyncedPattern =
74
76
  blocks.length === 1 &&
75
77
  blocks[ 0 ] &&
76
78
  isReusableBlock( blocks[ 0 ] ) &&
@@ -80,9 +82,15 @@ export default function PatternConvertButton( {
80
82
  blocks[ 0 ].attributes.ref
81
83
  );
82
84
 
85
+ const isUnsyncedPattern =
86
+ window?.__experimentalContentOnlyPatternInsertion &&
87
+ blocks.length === 1 &&
88
+ blocks?.[ 0 ]?.attributes?.metadata?.patternName;
89
+
83
90
  const _canConvert =
84
- // Hide when this is already a synced pattern.
85
- ! isReusable &&
91
+ // Hide when this is already a pattern.
92
+ ! isUnsyncedPattern &&
93
+ ! isSyncedPattern &&
86
94
  // Hide when patterns are disabled.
87
95
  canInsertBlockType( 'core/block', rootId ) &&
88
96
  blocks.every(
@@ -116,7 +124,20 @@ export default function PatternConvertButton( {
116
124
  }
117
125
 
118
126
  const handleSuccess = ( { pattern } ) => {
119
- if ( pattern.wp_pattern_sync_status !== PATTERN_SYNC_TYPES.unsynced ) {
127
+ if ( pattern.wp_pattern_sync_status === PATTERN_SYNC_TYPES.unsynced ) {
128
+ if ( clientIds?.length === 1 ) {
129
+ const existingAttributes = getBlockAttributes( clientIds[ 0 ] );
130
+ updateBlockAttributes( clientIds[ 0 ], {
131
+ metadata: {
132
+ ...( existingAttributes?.metadata
133
+ ? existingAttributes.metadata
134
+ : {} ),
135
+ patternName: `core/block/${ pattern.id }`,
136
+ name: pattern.title.raw,
137
+ },
138
+ } );
139
+ }
140
+ } else {
120
141
  const newBlock = createBlock( 'core/block', {
121
142
  ref: pattern.id,
122
143
  } );
@@ -16,22 +16,43 @@ import { store as patternsStore } from '../store';
16
16
  import { unlock } from '../lock-unlock';
17
17
 
18
18
  function PatternsManageButton( { clientId } ) {
19
- const { canRemove, isVisible, managePatternsUrl } = useSelect(
19
+ const {
20
+ attributes,
21
+ canDetach,
22
+ isVisible,
23
+ managePatternsUrl,
24
+ isSyncedPattern,
25
+ isUnsyncedPattern,
26
+ } = useSelect(
20
27
  ( select ) => {
21
- const { getBlock, canRemoveBlock } = select( blockEditorStore );
28
+ const { canRemoveBlock, getBlock } = select( blockEditorStore );
22
29
  const { canUser } = select( coreStore );
23
- const reusableBlock = getBlock( clientId );
30
+ const block = getBlock( clientId );
31
+
32
+ const _isUnsyncedPattern =
33
+ window?.__experimentalContentOnlyPatternInsertion &&
34
+ !! block?.attributes?.metadata?.patternName;
35
+
36
+ const _isSyncedPattern =
37
+ !! block &&
38
+ isReusableBlock( block ) &&
39
+ !! canUser( 'update', {
40
+ kind: 'postType',
41
+ name: 'wp_block',
42
+ id: block.attributes.ref,
43
+ } );
24
44
 
25
45
  return {
26
- canRemove: canRemoveBlock( clientId ),
27
- isVisible:
28
- !! reusableBlock &&
29
- isReusableBlock( reusableBlock ) &&
30
- !! canUser( 'update', {
31
- kind: 'postType',
32
- name: 'wp_block',
33
- id: reusableBlock.attributes.ref,
34
- } ),
46
+ attributes: block.attributes,
47
+ // For unsynced patterns, detaching is simply removing the `patternName` attribute.
48
+ // For synced patterns, the `core:block` block is replaced with its inner blocks,
49
+ // so checking whether `canRemoveBlock` is possible is required.
50
+ canDetach:
51
+ _isUnsyncedPattern ||
52
+ ( _isSyncedPattern && canRemoveBlock( clientId ) ),
53
+ isUnsyncedPattern: _isUnsyncedPattern,
54
+ isSyncedPattern: _isSyncedPattern,
55
+ isVisible: _isUnsyncedPattern || _isSyncedPattern,
35
56
  // The site editor and templates both check whether the user
36
57
  // has edit_theme_options capabilities. We can leverage that here
37
58
  // and omit the manage patterns link if the user can't access it.
@@ -50,6 +71,8 @@ function PatternsManageButton( { clientId } ) {
50
71
  [ clientId ]
51
72
  );
52
73
 
74
+ const { updateBlockAttributes } = useDispatch( blockEditorStore );
75
+
53
76
  // Ignore reason: false positive of the lint rule.
54
77
  // eslint-disable-next-line @wordpress/no-unused-vars-before-return
55
78
  const { convertSyncedPatternToStatic } = unlock(
@@ -62,9 +85,23 @@ function PatternsManageButton( { clientId } ) {
62
85
 
63
86
  return (
64
87
  <>
65
- { canRemove && (
88
+ { canDetach && (
66
89
  <MenuItem
67
- onClick={ () => convertSyncedPatternToStatic( clientId ) }
90
+ onClick={ () => {
91
+ if ( isSyncedPattern ) {
92
+ convertSyncedPatternToStatic( clientId );
93
+ }
94
+
95
+ if ( isUnsyncedPattern ) {
96
+ const {
97
+ patternName,
98
+ ...attributesWithoutPatternName
99
+ } = attributes?.metadata ?? {};
100
+ updateBlockAttributes( clientId, {
101
+ metadata: attributesWithoutPatternName,
102
+ } );
103
+ }
104
+ } }
68
105
  >
69
106
  { __( 'Detach' ) }
70
107
  </MenuItem>