@wordpress/patterns 1.15.0 → 1.17.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 +4 -0
- package/build/api/index.js +22 -0
- package/build/api/index.js.map +1 -0
- package/build/components/allow-overrides-modal.js +114 -0
- package/build/components/allow-overrides-modal.js.map +1 -0
- package/build/components/category-selector.js.map +1 -1
- package/build/components/create-pattern-modal.js.map +1 -1
- package/build/components/duplicate-pattern-modal.js.map +1 -1
- package/build/components/index.js.map +1 -1
- package/build/components/overrides-panel.js +44 -0
- package/build/components/overrides-panel.js.map +1 -0
- package/build/components/pattern-convert-button.js.map +1 -1
- package/build/components/pattern-overrides-controls.js +107 -0
- package/build/components/pattern-overrides-controls.js.map +1 -0
- package/build/components/patterns-manage-button.js.map +1 -1
- package/build/components/rename-pattern-category-modal.js.map +1 -1
- package/build/components/rename-pattern-modal.js.map +1 -1
- package/build/components/reset-overrides-control.js.map +1 -1
- package/build/constants.js +2 -1
- package/build/constants.js.map +1 -1
- package/build/index.js.map +1 -1
- package/build/index.native.js.map +1 -1
- package/build/lock-unlock.js.map +1 -1
- package/build/private-apis.js +7 -3
- package/build/private-apis.js.map +1 -1
- package/build/private-hooks.js.map +1 -1
- package/build/store/actions.js.map +1 -1
- package/build/store/constants.js.map +1 -1
- package/build/store/index.js +1 -1
- package/build/store/index.js.map +1 -1
- package/build/store/reducer.js.map +1 -1
- package/build/store/selectors.js.map +1 -1
- package/build-module/api/index.js +16 -0
- package/build-module/api/index.js.map +1 -0
- package/build-module/components/allow-overrides-modal.js +106 -0
- package/build-module/components/allow-overrides-modal.js.map +1 -0
- package/build-module/components/category-selector.js.map +1 -1
- package/build-module/components/create-pattern-modal.js.map +1 -1
- package/build-module/components/duplicate-pattern-modal.js.map +1 -1
- package/build-module/components/index.js.map +1 -1
- package/build-module/components/overrides-panel.js +37 -0
- package/build-module/components/overrides-panel.js.map +1 -0
- package/build-module/components/pattern-convert-button.js.map +1 -1
- package/build-module/components/pattern-overrides-controls.js +100 -0
- package/build-module/components/pattern-overrides-controls.js.map +1 -0
- package/build-module/components/patterns-manage-button.js.map +1 -1
- package/build-module/components/rename-pattern-category-modal.js.map +1 -1
- package/build-module/components/rename-pattern-modal.js.map +1 -1
- package/build-module/components/reset-overrides-control.js.map +1 -1
- package/build-module/constants.js +1 -0
- package/build-module/constants.js.map +1 -1
- package/build-module/index.js.map +1 -1
- package/build-module/index.native.js.map +1 -1
- package/build-module/lock-unlock.js.map +1 -1
- package/build-module/private-apis.js +6 -2
- package/build-module/private-apis.js.map +1 -1
- package/build-module/private-hooks.js.map +1 -1
- package/build-module/store/actions.js.map +1 -1
- package/build-module/store/constants.js.map +1 -1
- package/build-module/store/index.js.map +1 -1
- package/build-module/store/reducer.js.map +1 -1
- package/build-module/store/selectors.js.map +1 -1
- package/build-style/style-rtl.css +6 -1
- package/build-style/style.css +6 -1
- package/package.json +16 -16
- package/src/api/index.js +24 -0
- package/src/components/allow-overrides-modal.js +149 -0
- package/src/components/overrides-panel.js +45 -0
- package/src/components/pattern-overrides-controls.js +145 -0
- package/src/components/style.scss +6 -0
- package/src/constants.js +2 -0
- package/src/private-apis.js +6 -2
- package/build/components/use-set-pattern-bindings.js +0 -103
- package/build/components/use-set-pattern-bindings.js.map +0 -1
- package/build-module/components/use-set-pattern-bindings.js +0 -96
- package/build-module/components/use-set-pattern-bindings.js.map +0 -1
- package/src/components/use-set-pattern-bindings.js +0 -120
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["cloneBlock","store","coreStore","blockEditorStore","PATTERN_SYNC_TYPES","createPattern","title","syncType","content","categories","registry","meta","unsynced","wp_pattern_sync_status","undefined","reusableBlock","status","wp_pattern_category","updatedRecord","dispatch","saveEntityRecord","createPatternFromFile","file","fileContent","text","parsedContent","JSON","parse","e","Error","__file","syncStatus","pattern","convertSyncedPatternToStatic","clientId","patternBlock","select","getBlock","cloneBlocksAndRemoveBindings","blocks","map","block","metadata","attributes","id","bindings","Object","keys","length","innerBlocks","replaceBlocks","setEditingPattern","isEditing","type"],"sources":["@wordpress/patterns/src/store/actions.js"],"sourcesContent":["/**\n * WordPress dependencies\n */\n\nimport { cloneBlock } from '@wordpress/blocks';\nimport { store as coreStore } from '@wordpress/core-data';\nimport { store as blockEditorStore } from '@wordpress/block-editor';\n\n/**\n * Internal dependencies\n */\nimport { PATTERN_SYNC_TYPES } from '../constants';\n\n/**\n * Returns a generator converting one or more static blocks into a pattern, or creating a new empty pattern.\n *\n * @param {string} title Pattern title.\n * @param {'full'|'unsynced'} syncType They way block is synced, 'full' or 'unsynced'.\n * @param {string|undefined} [content] Optional serialized content of blocks to convert to pattern.\n * @param {number[]|undefined} [categories] Ids of any selected categories.\n */\nexport const createPattern =\n\t( title, syncType, content, categories ) =>\n\tasync ( { registry } ) => {\n\t\tconst meta =\n\t\t\tsyncType === PATTERN_SYNC_TYPES.unsynced\n\t\t\t\t? {\n\t\t\t\t\t\twp_pattern_sync_status: syncType,\n\t\t\t\t }\n\t\t\t\t: undefined;\n\n\t\tconst reusableBlock = {\n\t\t\ttitle,\n\t\t\tcontent,\n\t\t\tstatus: 'publish',\n\t\t\tmeta,\n\t\t\twp_pattern_category: categories,\n\t\t};\n\n\t\tconst updatedRecord = await registry\n\t\t\t.dispatch( coreStore )\n\t\t\t.saveEntityRecord( 'postType', 'wp_block', reusableBlock );\n\n\t\treturn updatedRecord;\n\t};\n\n/**\n * Create a pattern from a JSON file.\n * @param {File} file The JSON file instance of the pattern.\n * @param {number[]|undefined} [categories] Ids of any selected categories.\n */\nexport const createPatternFromFile =\n\t( file, categories ) =>\n\tasync ( { dispatch } ) => {\n\t\tconst fileContent = await file.text();\n\t\t/** @type {import('./types').PatternJSON} */\n\t\tlet parsedContent;\n\t\ttry {\n\t\t\tparsedContent = JSON.parse( fileContent );\n\t\t} catch ( e ) {\n\t\t\tthrow new Error( 'Invalid JSON file' );\n\t\t}\n\t\tif (\n\t\t\tparsedContent.__file !== 'wp_block' ||\n\t\t\t! parsedContent.title ||\n\t\t\t! parsedContent.content ||\n\t\t\ttypeof parsedContent.title !== 'string' ||\n\t\t\ttypeof parsedContent.content !== 'string' ||\n\t\t\t( parsedContent.syncStatus &&\n\t\t\t\ttypeof parsedContent.syncStatus !== 'string' )\n\t\t) {\n\t\t\tthrow new Error( 'Invalid pattern JSON file' );\n\t\t}\n\n\t\tconst pattern = await dispatch.createPattern(\n\t\t\tparsedContent.title,\n\t\t\tparsedContent.syncStatus,\n\t\t\tparsedContent.content,\n\t\t\tcategories\n\t\t);\n\n\t\treturn pattern;\n\t};\n\n/**\n * Returns a generator converting a synced pattern block into a static block.\n *\n * @param {string} clientId The client ID of the block to attach.\n */\nexport const convertSyncedPatternToStatic =\n\t( clientId ) =>\n\t( { registry } ) => {\n\t\tconst patternBlock = registry\n\t\t\t.select( blockEditorStore )\n\t\t\t.getBlock( clientId );\n\n\t\tfunction cloneBlocksAndRemoveBindings( blocks ) {\n\t\t\treturn blocks.map( ( block ) => {\n\t\t\t\tlet metadata = block.attributes.metadata;\n\t\t\t\tif ( metadata ) {\n\t\t\t\t\tmetadata = { ...metadata };\n\t\t\t\t\tdelete metadata.id;\n\t\t\t\t\tdelete metadata.bindings;\n\t\t\t\t}\n\t\t\t\treturn cloneBlock(\n\t\t\t\t\tblock,\n\t\t\t\t\t{\n\t\t\t\t\t\tmetadata:\n\t\t\t\t\t\t\tmetadata && Object.keys( metadata ).length > 0\n\t\t\t\t\t\t\t\t? metadata\n\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t},\n\t\t\t\t\tcloneBlocksAndRemoveBindings( block.innerBlocks )\n\t\t\t\t);\n\t\t\t} );\n\t\t}\n\n\t\tregistry\n\t\t\t.dispatch( blockEditorStore )\n\t\t\t.replaceBlocks(\n\t\t\t\tpatternBlock.clientId,\n\t\t\t\tcloneBlocksAndRemoveBindings( patternBlock.innerBlocks )\n\t\t\t);\n\t};\n\n/**\n * Returns an action descriptor for SET_EDITING_PATTERN action.\n *\n * @param {string} clientId The clientID of the pattern to target.\n * @param {boolean} isEditing Whether the block should be in editing state.\n * @return {Object} Action descriptor.\n */\nexport function setEditingPattern( clientId, isEditing ) {\n\treturn {\n\t\ttype: 'SET_EDITING_PATTERN',\n\t\tclientId,\n\t\tisEditing,\n\t};\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"names":["cloneBlock","store","coreStore","blockEditorStore","PATTERN_SYNC_TYPES","createPattern","title","syncType","content","categories","registry","meta","unsynced","wp_pattern_sync_status","undefined","reusableBlock","status","wp_pattern_category","updatedRecord","dispatch","saveEntityRecord","createPatternFromFile","file","fileContent","text","parsedContent","JSON","parse","e","Error","__file","syncStatus","pattern","convertSyncedPatternToStatic","clientId","patternBlock","select","getBlock","cloneBlocksAndRemoveBindings","blocks","map","block","metadata","attributes","id","bindings","Object","keys","length","innerBlocks","replaceBlocks","setEditingPattern","isEditing","type"],"sources":["@wordpress/patterns/src/store/actions.js"],"sourcesContent":["/**\n * WordPress dependencies\n */\n\nimport { cloneBlock } from '@wordpress/blocks';\nimport { store as coreStore } from '@wordpress/core-data';\nimport { store as blockEditorStore } from '@wordpress/block-editor';\n\n/**\n * Internal dependencies\n */\nimport { PATTERN_SYNC_TYPES } from '../constants';\n\n/**\n * Returns a generator converting one or more static blocks into a pattern, or creating a new empty pattern.\n *\n * @param {string} title Pattern title.\n * @param {'full'|'unsynced'} syncType They way block is synced, 'full' or 'unsynced'.\n * @param {string|undefined} [content] Optional serialized content of blocks to convert to pattern.\n * @param {number[]|undefined} [categories] Ids of any selected categories.\n */\nexport const createPattern =\n\t( title, syncType, content, categories ) =>\n\tasync ( { registry } ) => {\n\t\tconst meta =\n\t\t\tsyncType === PATTERN_SYNC_TYPES.unsynced\n\t\t\t\t? {\n\t\t\t\t\t\twp_pattern_sync_status: syncType,\n\t\t\t\t }\n\t\t\t\t: undefined;\n\n\t\tconst reusableBlock = {\n\t\t\ttitle,\n\t\t\tcontent,\n\t\t\tstatus: 'publish',\n\t\t\tmeta,\n\t\t\twp_pattern_category: categories,\n\t\t};\n\n\t\tconst updatedRecord = await registry\n\t\t\t.dispatch( coreStore )\n\t\t\t.saveEntityRecord( 'postType', 'wp_block', reusableBlock );\n\n\t\treturn updatedRecord;\n\t};\n\n/**\n * Create a pattern from a JSON file.\n * @param {File} file The JSON file instance of the pattern.\n * @param {number[]|undefined} [categories] Ids of any selected categories.\n */\nexport const createPatternFromFile =\n\t( file, categories ) =>\n\tasync ( { dispatch } ) => {\n\t\tconst fileContent = await file.text();\n\t\t/** @type {import('./types').PatternJSON} */\n\t\tlet parsedContent;\n\t\ttry {\n\t\t\tparsedContent = JSON.parse( fileContent );\n\t\t} catch ( e ) {\n\t\t\tthrow new Error( 'Invalid JSON file' );\n\t\t}\n\t\tif (\n\t\t\tparsedContent.__file !== 'wp_block' ||\n\t\t\t! parsedContent.title ||\n\t\t\t! parsedContent.content ||\n\t\t\ttypeof parsedContent.title !== 'string' ||\n\t\t\ttypeof parsedContent.content !== 'string' ||\n\t\t\t( parsedContent.syncStatus &&\n\t\t\t\ttypeof parsedContent.syncStatus !== 'string' )\n\t\t) {\n\t\t\tthrow new Error( 'Invalid pattern JSON file' );\n\t\t}\n\n\t\tconst pattern = await dispatch.createPattern(\n\t\t\tparsedContent.title,\n\t\t\tparsedContent.syncStatus,\n\t\t\tparsedContent.content,\n\t\t\tcategories\n\t\t);\n\n\t\treturn pattern;\n\t};\n\n/**\n * Returns a generator converting a synced pattern block into a static block.\n *\n * @param {string} clientId The client ID of the block to attach.\n */\nexport const convertSyncedPatternToStatic =\n\t( clientId ) =>\n\t( { registry } ) => {\n\t\tconst patternBlock = registry\n\t\t\t.select( blockEditorStore )\n\t\t\t.getBlock( clientId );\n\n\t\tfunction cloneBlocksAndRemoveBindings( blocks ) {\n\t\t\treturn blocks.map( ( block ) => {\n\t\t\t\tlet metadata = block.attributes.metadata;\n\t\t\t\tif ( metadata ) {\n\t\t\t\t\tmetadata = { ...metadata };\n\t\t\t\t\tdelete metadata.id;\n\t\t\t\t\tdelete metadata.bindings;\n\t\t\t\t}\n\t\t\t\treturn cloneBlock(\n\t\t\t\t\tblock,\n\t\t\t\t\t{\n\t\t\t\t\t\tmetadata:\n\t\t\t\t\t\t\tmetadata && Object.keys( metadata ).length > 0\n\t\t\t\t\t\t\t\t? metadata\n\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t},\n\t\t\t\t\tcloneBlocksAndRemoveBindings( block.innerBlocks )\n\t\t\t\t);\n\t\t\t} );\n\t\t}\n\n\t\tregistry\n\t\t\t.dispatch( blockEditorStore )\n\t\t\t.replaceBlocks(\n\t\t\t\tpatternBlock.clientId,\n\t\t\t\tcloneBlocksAndRemoveBindings( patternBlock.innerBlocks )\n\t\t\t);\n\t};\n\n/**\n * Returns an action descriptor for SET_EDITING_PATTERN action.\n *\n * @param {string} clientId The clientID of the pattern to target.\n * @param {boolean} isEditing Whether the block should be in editing state.\n * @return {Object} Action descriptor.\n */\nexport function setEditingPattern( clientId, isEditing ) {\n\treturn {\n\t\ttype: 'SET_EDITING_PATTERN',\n\t\tclientId,\n\t\tisEditing,\n\t};\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["STORE_NAME"],"sources":["@wordpress/patterns/src/store/constants.js"],"sourcesContent":["/**\n * Module Constants\n */\nexport const STORE_NAME = 'core/patterns';\n"],"mappings":"AAAA;AACA;AACA;AACA,OAAO,MAAMA,UAAU,GAAG,eAAe"}
|
|
1
|
+
{"version":3,"names":["STORE_NAME"],"sources":["@wordpress/patterns/src/store/constants.js"],"sourcesContent":["/**\n * Module Constants\n */\nexport const STORE_NAME = 'core/patterns';\n"],"mappings":"AAAA;AACA;AACA;AACA,OAAO,MAAMA,UAAU,GAAG,eAAe","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["createReduxStore","register","reducer","actions","STORE_NAME","selectors","unlock","storeConfig","store","registerPrivateActions","registerPrivateSelectors"],"sources":["@wordpress/patterns/src/store/index.js"],"sourcesContent":["/**\n * WordPress dependencies\n */\nimport { createReduxStore, register } from '@wordpress/data';\n\n/**\n * Internal dependencies\n */\nimport reducer from './reducer';\nimport * as actions from './actions';\nimport { STORE_NAME } from './constants';\nimport * as selectors from './selectors';\nimport { unlock } from '../lock-unlock';\n\n/**\n * Post editor data store configuration.\n *\n * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/data/README.md#registerStore\n *\n * @type {Object}\n */\nexport const storeConfig = {\n\treducer,\n};\n\n/**\n * Store definition for the editor namespace.\n *\n * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/data/README.md#createReduxStore\n *\n * @type {Object}\n */\nexport const store = createReduxStore( STORE_NAME, {\n\t...storeConfig,\n} );\n\nregister( store );\nunlock( store ).registerPrivateActions( actions );\nunlock( store ).registerPrivateSelectors( selectors );\n"],"mappings":"AAAA;AACA;AACA;AACA,SAASA,gBAAgB,EAAEC,QAAQ,QAAQ,iBAAiB;;AAE5D;AACA;AACA;AACA,OAAOC,OAAO,MAAM,WAAW;AAC/B,OAAO,KAAKC,OAAO,MAAM,WAAW;AACpC,SAASC,UAAU,QAAQ,aAAa;AACxC,OAAO,KAAKC,SAAS,MAAM,aAAa;AACxC,SAASC,MAAM,QAAQ,gBAAgB;;AAEvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,WAAW,GAAG;EAC1BL;AACD,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMM,KAAK,GAAGR,gBAAgB,CAAEI,UAAU,EAAE;EAClD,GAAGG;AACJ,CAAE,CAAC;AAEHN,QAAQ,CAAEO,KAAM,CAAC;AACjBF,MAAM,CAAEE,KAAM,CAAC,CAACC,sBAAsB,CAAEN,OAAQ,CAAC;AACjDG,MAAM,CAAEE,KAAM,CAAC,CAACE,wBAAwB,CAAEL,SAAU,CAAC"}
|
|
1
|
+
{"version":3,"names":["createReduxStore","register","reducer","actions","STORE_NAME","selectors","unlock","storeConfig","store","registerPrivateActions","registerPrivateSelectors"],"sources":["@wordpress/patterns/src/store/index.js"],"sourcesContent":["/**\n * WordPress dependencies\n */\nimport { createReduxStore, register } from '@wordpress/data';\n\n/**\n * Internal dependencies\n */\nimport reducer from './reducer';\nimport * as actions from './actions';\nimport { STORE_NAME } from './constants';\nimport * as selectors from './selectors';\nimport { unlock } from '../lock-unlock';\n\n/**\n * Post editor data store configuration.\n *\n * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/data/README.md#registerStore\n *\n * @type {Object}\n */\nexport const storeConfig = {\n\treducer,\n};\n\n/**\n * Store definition for the editor namespace.\n *\n * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/data/README.md#createReduxStore\n *\n * @type {Object}\n */\nexport const store = createReduxStore( STORE_NAME, {\n\t...storeConfig,\n} );\n\nregister( store );\nunlock( store ).registerPrivateActions( actions );\nunlock( store ).registerPrivateSelectors( selectors );\n"],"mappings":"AAAA;AACA;AACA;AACA,SAASA,gBAAgB,EAAEC,QAAQ,QAAQ,iBAAiB;;AAE5D;AACA;AACA;AACA,OAAOC,OAAO,MAAM,WAAW;AAC/B,OAAO,KAAKC,OAAO,MAAM,WAAW;AACpC,SAASC,UAAU,QAAQ,aAAa;AACxC,OAAO,KAAKC,SAAS,MAAM,aAAa;AACxC,SAASC,MAAM,QAAQ,gBAAgB;;AAEvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,WAAW,GAAG;EAC1BL;AACD,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMM,KAAK,GAAGR,gBAAgB,CAAEI,UAAU,EAAE;EAClD,GAAGG;AACJ,CAAE,CAAC;AAEHN,QAAQ,CAAEO,KAAM,CAAC;AACjBF,MAAM,CAAEE,KAAM,CAAC,CAACC,sBAAsB,CAAEN,OAAQ,CAAC;AACjDG,MAAM,CAAEE,KAAM,CAAC,CAACE,wBAAwB,CAAEL,SAAU,CAAC","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["combineReducers","isEditingPattern","state","action","type","clientId","isEditing"],"sources":["@wordpress/patterns/src/store/reducer.js"],"sourcesContent":["/**\n * WordPress dependencies\n */\nimport { combineReducers } from '@wordpress/data';\n\nexport function isEditingPattern( state = {}, action ) {\n\tif ( action?.type === 'SET_EDITING_PATTERN' ) {\n\t\treturn {\n\t\t\t...state,\n\t\t\t[ action.clientId ]: action.isEditing,\n\t\t};\n\t}\n\n\treturn state;\n}\n\nexport default combineReducers( {\n\tisEditingPattern,\n} );\n"],"mappings":"AAAA;AACA;AACA;AACA,SAASA,eAAe,QAAQ,iBAAiB;AAEjD,OAAO,SAASC,gBAAgBA,CAAEC,KAAK,GAAG,CAAC,CAAC,EAAEC,MAAM,EAAG;EACtD,IAAKA,MAAM,EAAEC,IAAI,KAAK,qBAAqB,EAAG;IAC7C,OAAO;MACN,GAAGF,KAAK;MACR,CAAEC,MAAM,CAACE,QAAQ,GAAIF,MAAM,CAACG;IAC7B,CAAC;EACF;EAEA,OAAOJ,KAAK;AACb;AAEA,eAAeF,eAAe,CAAE;EAC/BC;AACD,CAAE,CAAC"}
|
|
1
|
+
{"version":3,"names":["combineReducers","isEditingPattern","state","action","type","clientId","isEditing"],"sources":["@wordpress/patterns/src/store/reducer.js"],"sourcesContent":["/**\n * WordPress dependencies\n */\nimport { combineReducers } from '@wordpress/data';\n\nexport function isEditingPattern( state = {}, action ) {\n\tif ( action?.type === 'SET_EDITING_PATTERN' ) {\n\t\treturn {\n\t\t\t...state,\n\t\t\t[ action.clientId ]: action.isEditing,\n\t\t};\n\t}\n\n\treturn state;\n}\n\nexport default combineReducers( {\n\tisEditingPattern,\n} );\n"],"mappings":"AAAA;AACA;AACA;AACA,SAASA,eAAe,QAAQ,iBAAiB;AAEjD,OAAO,SAASC,gBAAgBA,CAAEC,KAAK,GAAG,CAAC,CAAC,EAAEC,MAAM,EAAG;EACtD,IAAKA,MAAM,EAAEC,IAAI,KAAK,qBAAqB,EAAG;IAC7C,OAAO;MACN,GAAGF,KAAK;MACR,CAAEC,MAAM,CAACE,QAAQ,GAAIF,MAAM,CAACG;IAC7B,CAAC;EACF;EAEA,OAAOJ,KAAK;AACb;AAEA,eAAeF,eAAe,CAAE;EAC/BC;AACD,CAAE,CAAC","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["isEditingPattern","state","clientId"],"sources":["@wordpress/patterns/src/store/selectors.js"],"sourcesContent":["/**\n * Returns true if pattern is in the editing state.\n *\n * @param {Object} state Global application state.\n * @param {number} clientId the clientID of the block.\n * @return {boolean} Whether the pattern is in the editing state.\n */\nexport function isEditingPattern( state, clientId ) {\n\treturn state.isEditingPattern[ clientId ];\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASA,gBAAgBA,CAAEC,KAAK,EAAEC,QAAQ,EAAG;EACnD,OAAOD,KAAK,CAACD,gBAAgB,CAAEE,QAAQ,CAAE;AAC1C"}
|
|
1
|
+
{"version":3,"names":["isEditingPattern","state","clientId"],"sources":["@wordpress/patterns/src/store/selectors.js"],"sourcesContent":["/**\n * Returns true if pattern is in the editing state.\n *\n * @param {Object} state Global application state.\n * @param {number} clientId the clientID of the block.\n * @return {boolean} Whether the pattern is in the editing state.\n */\nexport function isEditingPattern( state, clientId ) {\n\treturn state.isEditingPattern[ clientId ];\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASA,gBAAgBA,CAAEC,KAAK,EAAEC,QAAQ,EAAG;EACnD,OAAOD,KAAK,CAACD,gBAAgB,CAAEE,QAAQ,CAAE;AAC1C","ignoreList":[]}
|
|
@@ -96,7 +96,7 @@
|
|
|
96
96
|
--wp-admin-border-width-focus: 2px;
|
|
97
97
|
--wp-block-synced-color: #7a00df;
|
|
98
98
|
--wp-block-synced-color--rgb: 122, 0, 223;
|
|
99
|
-
--wp-bound-block-color:
|
|
99
|
+
--wp-bound-block-color: var(--wp-block-synced-color);
|
|
100
100
|
}
|
|
101
101
|
@media (min-resolution: 192dpi) {
|
|
102
102
|
:root {
|
|
@@ -139,4 +139,9 @@
|
|
|
139
139
|
.patterns-rename-pattern-category-modal__validation-message {
|
|
140
140
|
width: 320px;
|
|
141
141
|
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.pattern-overrides-control__allow-overrides-button {
|
|
145
|
+
width: 100%;
|
|
146
|
+
justify-content: center;
|
|
142
147
|
}
|
package/build-style/style.css
CHANGED
|
@@ -96,7 +96,7 @@
|
|
|
96
96
|
--wp-admin-border-width-focus: 2px;
|
|
97
97
|
--wp-block-synced-color: #7a00df;
|
|
98
98
|
--wp-block-synced-color--rgb: 122, 0, 223;
|
|
99
|
-
--wp-bound-block-color:
|
|
99
|
+
--wp-bound-block-color: var(--wp-block-synced-color);
|
|
100
100
|
}
|
|
101
101
|
@media (min-resolution: 192dpi) {
|
|
102
102
|
:root {
|
|
@@ -139,4 +139,9 @@
|
|
|
139
139
|
.patterns-rename-pattern-category-modal__validation-message {
|
|
140
140
|
width: 320px;
|
|
141
141
|
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.pattern-overrides-control__allow-overrides-button {
|
|
145
|
+
width: 100%;
|
|
146
|
+
justify-content: center;
|
|
142
147
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wordpress/patterns",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.17.0",
|
|
4
4
|
"description": "Management of user pattern editing.",
|
|
5
5
|
"author": "The WordPress Contributors",
|
|
6
6
|
"license": "GPL-2.0-or-later",
|
|
@@ -31,20 +31,20 @@
|
|
|
31
31
|
],
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@babel/runtime": "^7.16.0",
|
|
34
|
-
"@wordpress/a11y": "^3.
|
|
35
|
-
"@wordpress/block-editor": "^12.
|
|
36
|
-
"@wordpress/blocks": "^12.
|
|
37
|
-
"@wordpress/components": "^27.
|
|
38
|
-
"@wordpress/compose": "^6.
|
|
39
|
-
"@wordpress/core-data": "^6.
|
|
40
|
-
"@wordpress/data": "^9.
|
|
41
|
-
"@wordpress/element": "^5.
|
|
42
|
-
"@wordpress/html-entities": "^3.
|
|
43
|
-
"@wordpress/i18n": "^4.
|
|
44
|
-
"@wordpress/icons": "^9.
|
|
45
|
-
"@wordpress/notices": "^4.
|
|
46
|
-
"@wordpress/private-apis": "^0.
|
|
47
|
-
"@wordpress/url": "^3.
|
|
34
|
+
"@wordpress/a11y": "^3.56.0",
|
|
35
|
+
"@wordpress/block-editor": "^12.24.0",
|
|
36
|
+
"@wordpress/blocks": "^12.33.0",
|
|
37
|
+
"@wordpress/components": "^27.4.0",
|
|
38
|
+
"@wordpress/compose": "^6.33.0",
|
|
39
|
+
"@wordpress/core-data": "^6.33.0",
|
|
40
|
+
"@wordpress/data": "^9.26.0",
|
|
41
|
+
"@wordpress/element": "^5.33.0",
|
|
42
|
+
"@wordpress/html-entities": "^3.56.0",
|
|
43
|
+
"@wordpress/i18n": "^4.56.0",
|
|
44
|
+
"@wordpress/icons": "^9.47.0",
|
|
45
|
+
"@wordpress/notices": "^4.24.0",
|
|
46
|
+
"@wordpress/private-apis": "^0.38.0",
|
|
47
|
+
"@wordpress/url": "^3.57.0"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
50
|
"react": "^18.0.0",
|
|
@@ -53,5 +53,5 @@
|
|
|
53
53
|
"publishConfig": {
|
|
54
54
|
"access": "public"
|
|
55
55
|
},
|
|
56
|
-
"gitHead": "
|
|
56
|
+
"gitHead": "280403b4c1cf6cc2c55a6c4d56f9ef91145e4191"
|
|
57
57
|
}
|
package/src/api/index.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { PARTIAL_SYNCING_SUPPORTED_BLOCKS } from '../constants';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Determines whether a block is overridable.
|
|
8
|
+
*
|
|
9
|
+
* @param {WPBlock} block The block to test.
|
|
10
|
+
*
|
|
11
|
+
* @return {boolean} `true` if a block is overridable, `false` otherwise.
|
|
12
|
+
*/
|
|
13
|
+
export function isOverridableBlock( block ) {
|
|
14
|
+
return (
|
|
15
|
+
Object.keys( PARTIAL_SYNCING_SUPPORTED_BLOCKS ).includes(
|
|
16
|
+
block.name
|
|
17
|
+
) &&
|
|
18
|
+
!! block.attributes.metadata?.name &&
|
|
19
|
+
!! block.attributes.metadata?.bindings &&
|
|
20
|
+
Object.values( block.attributes.metadata.bindings ).some(
|
|
21
|
+
( binding ) => binding.source === 'core/pattern-overrides'
|
|
22
|
+
)
|
|
23
|
+
);
|
|
24
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import {
|
|
5
|
+
__experimentalHStack as HStack,
|
|
6
|
+
__experimentalVStack as VStack,
|
|
7
|
+
Button,
|
|
8
|
+
__experimentalText as Text,
|
|
9
|
+
TextControl,
|
|
10
|
+
Modal,
|
|
11
|
+
} from '@wordpress/components';
|
|
12
|
+
import { __, sprintf } from '@wordpress/i18n';
|
|
13
|
+
import { useState, useId } from '@wordpress/element';
|
|
14
|
+
import { speak } from '@wordpress/a11y';
|
|
15
|
+
|
|
16
|
+
export function AllowOverridesModal( {
|
|
17
|
+
placeholder,
|
|
18
|
+
initialName = '',
|
|
19
|
+
onClose,
|
|
20
|
+
onSave,
|
|
21
|
+
} ) {
|
|
22
|
+
const [ editedBlockName, setEditedBlockName ] = useState( initialName );
|
|
23
|
+
const descriptionId = useId();
|
|
24
|
+
|
|
25
|
+
const isNameValid = !! editedBlockName.trim();
|
|
26
|
+
|
|
27
|
+
const handleSubmit = () => {
|
|
28
|
+
if ( editedBlockName !== initialName ) {
|
|
29
|
+
const message = sprintf(
|
|
30
|
+
/* translators: %s: new name/label for the block */
|
|
31
|
+
__( 'Block name changed to: "%s".' ),
|
|
32
|
+
editedBlockName
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
// Must be assertive to immediately announce change.
|
|
36
|
+
speak( message, 'assertive' );
|
|
37
|
+
}
|
|
38
|
+
onSave( editedBlockName );
|
|
39
|
+
|
|
40
|
+
// Immediate close avoids ability to hit save multiple times.
|
|
41
|
+
onClose();
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<Modal
|
|
46
|
+
title={ __( 'Enable overrides' ) }
|
|
47
|
+
onRequestClose={ onClose }
|
|
48
|
+
focusOnMount="firstContentElement"
|
|
49
|
+
aria={ { describedby: descriptionId } }
|
|
50
|
+
size="small"
|
|
51
|
+
>
|
|
52
|
+
<form
|
|
53
|
+
onSubmit={ ( event ) => {
|
|
54
|
+
event.preventDefault();
|
|
55
|
+
|
|
56
|
+
if ( ! isNameValid ) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
handleSubmit();
|
|
61
|
+
} }
|
|
62
|
+
>
|
|
63
|
+
<VStack spacing="6">
|
|
64
|
+
<Text id={ descriptionId }>
|
|
65
|
+
{ __(
|
|
66
|
+
'Overrides are changes you make to a block within a synced pattern instance. Use overrides to customize a synced pattern instance to suit its new context. Name this block to specify an override.'
|
|
67
|
+
) }
|
|
68
|
+
</Text>
|
|
69
|
+
<TextControl
|
|
70
|
+
__nextHasNoMarginBottom
|
|
71
|
+
__next40pxDefaultSize
|
|
72
|
+
value={ editedBlockName }
|
|
73
|
+
label={ __( 'Name' ) }
|
|
74
|
+
help={ __(
|
|
75
|
+
'For example, if you are creating a recipe pattern, you use "Recipe Title", "Recipe Description", etc.'
|
|
76
|
+
) }
|
|
77
|
+
placeholder={ placeholder }
|
|
78
|
+
onChange={ setEditedBlockName }
|
|
79
|
+
/>
|
|
80
|
+
<HStack justify="right">
|
|
81
|
+
<Button
|
|
82
|
+
__next40pxDefaultSize
|
|
83
|
+
variant="tertiary"
|
|
84
|
+
onClick={ onClose }
|
|
85
|
+
>
|
|
86
|
+
{ __( 'Cancel' ) }
|
|
87
|
+
</Button>
|
|
88
|
+
|
|
89
|
+
<Button
|
|
90
|
+
__next40pxDefaultSize
|
|
91
|
+
aria-disabled={ ! isNameValid }
|
|
92
|
+
variant="primary"
|
|
93
|
+
type="submit"
|
|
94
|
+
>
|
|
95
|
+
{ __( 'Enable' ) }
|
|
96
|
+
</Button>
|
|
97
|
+
</HStack>
|
|
98
|
+
</VStack>
|
|
99
|
+
</form>
|
|
100
|
+
</Modal>
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export function DisallowOverridesModal( { onClose, onSave } ) {
|
|
105
|
+
const descriptionId = useId();
|
|
106
|
+
|
|
107
|
+
return (
|
|
108
|
+
<Modal
|
|
109
|
+
title={ __( 'Disable overrides' ) }
|
|
110
|
+
onRequestClose={ onClose }
|
|
111
|
+
aria={ { describedby: descriptionId } }
|
|
112
|
+
size="small"
|
|
113
|
+
>
|
|
114
|
+
<form
|
|
115
|
+
onSubmit={ ( event ) => {
|
|
116
|
+
event.preventDefault();
|
|
117
|
+
onSave();
|
|
118
|
+
onClose();
|
|
119
|
+
} }
|
|
120
|
+
>
|
|
121
|
+
<VStack spacing="6">
|
|
122
|
+
<Text id={ descriptionId }>
|
|
123
|
+
{ __(
|
|
124
|
+
'Are you sure you want to disable overrides? Disabling overrides will revert all applied overrides for this block throughout instances of this pattern.'
|
|
125
|
+
) }
|
|
126
|
+
</Text>
|
|
127
|
+
|
|
128
|
+
<HStack justify="right">
|
|
129
|
+
<Button
|
|
130
|
+
__next40pxDefaultSize
|
|
131
|
+
variant="tertiary"
|
|
132
|
+
onClick={ onClose }
|
|
133
|
+
>
|
|
134
|
+
{ __( 'Cancel' ) }
|
|
135
|
+
</Button>
|
|
136
|
+
|
|
137
|
+
<Button
|
|
138
|
+
__next40pxDefaultSize
|
|
139
|
+
variant="primary"
|
|
140
|
+
type="submit"
|
|
141
|
+
>
|
|
142
|
+
{ __( 'Disable' ) }
|
|
143
|
+
</Button>
|
|
144
|
+
</HStack>
|
|
145
|
+
</VStack>
|
|
146
|
+
</form>
|
|
147
|
+
</Modal>
|
|
148
|
+
);
|
|
149
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import {
|
|
5
|
+
privateApis as blockEditorPrivateApis,
|
|
6
|
+
store as blockEditorStore,
|
|
7
|
+
} from '@wordpress/block-editor';
|
|
8
|
+
import { PanelBody } from '@wordpress/components';
|
|
9
|
+
import { useSelect } from '@wordpress/data';
|
|
10
|
+
import { useMemo } from '@wordpress/element';
|
|
11
|
+
import { __ } from '@wordpress/i18n';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Internal dependencies
|
|
15
|
+
*/
|
|
16
|
+
import { isOverridableBlock } from '../api';
|
|
17
|
+
import { unlock } from '../lock-unlock';
|
|
18
|
+
|
|
19
|
+
const { BlockQuickNavigation } = unlock( blockEditorPrivateApis );
|
|
20
|
+
|
|
21
|
+
export default function OverridesPanel() {
|
|
22
|
+
const allClientIds = useSelect(
|
|
23
|
+
( select ) => select( blockEditorStore ).getClientIdsWithDescendants(),
|
|
24
|
+
[]
|
|
25
|
+
);
|
|
26
|
+
const { getBlock } = useSelect( blockEditorStore );
|
|
27
|
+
const clientIdsWithOverrides = useMemo(
|
|
28
|
+
() =>
|
|
29
|
+
allClientIds.filter( ( clientId ) => {
|
|
30
|
+
const block = getBlock( clientId );
|
|
31
|
+
return isOverridableBlock( block );
|
|
32
|
+
} ),
|
|
33
|
+
[ allClientIds, getBlock ]
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
if ( ! clientIdsWithOverrides?.length ) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<PanelBody title={ __( 'Overrides' ) }>
|
|
42
|
+
<BlockQuickNavigation clientIds={ clientIdsWithOverrides } />
|
|
43
|
+
</PanelBody>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { useState, useId } from '@wordpress/element';
|
|
5
|
+
import { InspectorControls } from '@wordpress/block-editor';
|
|
6
|
+
import { BaseControl, Button } from '@wordpress/components';
|
|
7
|
+
import { __ } from '@wordpress/i18n';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Internal dependencies
|
|
11
|
+
*/
|
|
12
|
+
import {
|
|
13
|
+
PARTIAL_SYNCING_SUPPORTED_BLOCKS,
|
|
14
|
+
PATTERN_OVERRIDES_BINDING_SOURCE,
|
|
15
|
+
} from '../constants';
|
|
16
|
+
import {
|
|
17
|
+
AllowOverridesModal,
|
|
18
|
+
DisallowOverridesModal,
|
|
19
|
+
} from './allow-overrides-modal';
|
|
20
|
+
|
|
21
|
+
function removeBindings( bindings, syncedAttributes ) {
|
|
22
|
+
let updatedBindings = {};
|
|
23
|
+
for ( const attributeName of syncedAttributes ) {
|
|
24
|
+
// Omit any bindings that's not the same source from the `updatedBindings` object.
|
|
25
|
+
if (
|
|
26
|
+
bindings?.[ attributeName ]?.source !==
|
|
27
|
+
PATTERN_OVERRIDES_BINDING_SOURCE &&
|
|
28
|
+
bindings?.[ attributeName ]?.source !== undefined
|
|
29
|
+
) {
|
|
30
|
+
updatedBindings[ attributeName ] = bindings[ attributeName ];
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if ( ! Object.keys( updatedBindings ).length ) {
|
|
34
|
+
updatedBindings = undefined;
|
|
35
|
+
}
|
|
36
|
+
return updatedBindings;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function addBindings( bindings, syncedAttributes ) {
|
|
40
|
+
const updatedBindings = { ...bindings };
|
|
41
|
+
for ( const attributeName of syncedAttributes ) {
|
|
42
|
+
if ( ! bindings?.[ attributeName ] ) {
|
|
43
|
+
updatedBindings[ attributeName ] = {
|
|
44
|
+
source: PATTERN_OVERRIDES_BINDING_SOURCE,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return updatedBindings;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function PatternOverridesControls( { attributes, name, setAttributes } ) {
|
|
52
|
+
const controlId = useId();
|
|
53
|
+
const [ showAllowOverridesModal, setShowAllowOverridesModal ] =
|
|
54
|
+
useState( false );
|
|
55
|
+
const [ showDisallowOverridesModal, setShowDisallowOverridesModal ] =
|
|
56
|
+
useState( false );
|
|
57
|
+
|
|
58
|
+
const syncedAttributes = PARTIAL_SYNCING_SUPPORTED_BLOCKS[ name ];
|
|
59
|
+
const attributeSources = syncedAttributes.map(
|
|
60
|
+
( attributeName ) =>
|
|
61
|
+
attributes.metadata?.bindings?.[ attributeName ]?.source
|
|
62
|
+
);
|
|
63
|
+
const isConnectedToOtherSources = attributeSources.every(
|
|
64
|
+
( source ) => source && source !== 'core/pattern-overrides'
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
function updateBindings( isChecked, customName ) {
|
|
68
|
+
const prevBindings = attributes?.metadata?.bindings;
|
|
69
|
+
const updatedBindings = isChecked
|
|
70
|
+
? addBindings( prevBindings, syncedAttributes )
|
|
71
|
+
: removeBindings( prevBindings, syncedAttributes );
|
|
72
|
+
|
|
73
|
+
const updatedMetadata = {
|
|
74
|
+
...attributes.metadata,
|
|
75
|
+
bindings: updatedBindings,
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
if ( customName ) {
|
|
79
|
+
updatedMetadata.name = customName;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
setAttributes( {
|
|
83
|
+
metadata: updatedMetadata,
|
|
84
|
+
} );
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Avoid overwriting other (e.g. meta) bindings.
|
|
88
|
+
if ( isConnectedToOtherSources ) return null;
|
|
89
|
+
|
|
90
|
+
const hasName = !! attributes.metadata?.name;
|
|
91
|
+
const allowOverrides =
|
|
92
|
+
hasName &&
|
|
93
|
+
attributeSources.some(
|
|
94
|
+
( source ) => source === PATTERN_OVERRIDES_BINDING_SOURCE
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
return (
|
|
98
|
+
<>
|
|
99
|
+
<InspectorControls group="advanced">
|
|
100
|
+
<BaseControl
|
|
101
|
+
id={ controlId }
|
|
102
|
+
label={ __( 'Overrides' ) }
|
|
103
|
+
help={ __(
|
|
104
|
+
'Allow changes to this block throughout instances of this pattern.'
|
|
105
|
+
) }
|
|
106
|
+
>
|
|
107
|
+
<Button
|
|
108
|
+
__next40pxDefaultSize
|
|
109
|
+
className="pattern-overrides-control__allow-overrides-button"
|
|
110
|
+
variant="secondary"
|
|
111
|
+
onClick={ () => {
|
|
112
|
+
if ( allowOverrides ) {
|
|
113
|
+
setShowDisallowOverridesModal( true );
|
|
114
|
+
} else {
|
|
115
|
+
setShowAllowOverridesModal( true );
|
|
116
|
+
}
|
|
117
|
+
} }
|
|
118
|
+
>
|
|
119
|
+
{ allowOverrides
|
|
120
|
+
? __( 'Disable overrides' )
|
|
121
|
+
: __( 'Enable overrides' ) }
|
|
122
|
+
</Button>
|
|
123
|
+
</BaseControl>
|
|
124
|
+
</InspectorControls>
|
|
125
|
+
|
|
126
|
+
{ showAllowOverridesModal && (
|
|
127
|
+
<AllowOverridesModal
|
|
128
|
+
initialName={ attributes.metadata?.name }
|
|
129
|
+
onClose={ () => setShowAllowOverridesModal( false ) }
|
|
130
|
+
onSave={ ( newName ) => {
|
|
131
|
+
updateBindings( true, newName );
|
|
132
|
+
} }
|
|
133
|
+
/>
|
|
134
|
+
) }
|
|
135
|
+
{ showDisallowOverridesModal && (
|
|
136
|
+
<DisallowOverridesModal
|
|
137
|
+
onClose={ () => setShowDisallowOverridesModal( false ) }
|
|
138
|
+
onSave={ () => updateBindings( false ) }
|
|
139
|
+
/>
|
|
140
|
+
) }
|
|
141
|
+
</>
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export default PatternOverridesControls;
|
package/src/constants.js
CHANGED
package/src/private-apis.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Internal dependencies
|
|
3
3
|
*/
|
|
4
4
|
import { lock } from './lock-unlock';
|
|
5
|
+
import OverridesPanel from './components/overrides-panel';
|
|
5
6
|
import {
|
|
6
7
|
default as CreatePatternModal,
|
|
7
8
|
CreatePatternModalContents,
|
|
@@ -10,10 +11,11 @@ import {
|
|
|
10
11
|
default as DuplicatePatternModal,
|
|
11
12
|
useDuplicatePatternProps,
|
|
12
13
|
} from './components/duplicate-pattern-modal';
|
|
14
|
+
import { isOverridableBlock } from './api';
|
|
13
15
|
import RenamePatternModal from './components/rename-pattern-modal';
|
|
14
16
|
import PatternsMenuItems from './components';
|
|
15
17
|
import RenamePatternCategoryModal from './components/rename-pattern-category-modal';
|
|
16
|
-
import
|
|
18
|
+
import PatternOverridesControls from './components/pattern-overrides-controls';
|
|
17
19
|
import ResetOverridesControl from './components/reset-overrides-control';
|
|
18
20
|
import { useAddPatternCategory } from './private-hooks';
|
|
19
21
|
import {
|
|
@@ -27,14 +29,16 @@ import {
|
|
|
27
29
|
|
|
28
30
|
export const privateApis = {};
|
|
29
31
|
lock( privateApis, {
|
|
32
|
+
OverridesPanel,
|
|
30
33
|
CreatePatternModal,
|
|
31
34
|
CreatePatternModalContents,
|
|
32
35
|
DuplicatePatternModal,
|
|
36
|
+
isOverridableBlock,
|
|
33
37
|
useDuplicatePatternProps,
|
|
34
38
|
RenamePatternModal,
|
|
35
39
|
PatternsMenuItems,
|
|
36
40
|
RenamePatternCategoryModal,
|
|
37
|
-
|
|
41
|
+
PatternOverridesControls,
|
|
38
42
|
ResetOverridesControl,
|
|
39
43
|
useAddPatternCategory,
|
|
40
44
|
PATTERN_TYPES,
|