@wordpress/blocks
Version:
Block API for WordPress.
8 lines (7 loc) • 38.4 kB
Source Map (JSON)
{
"version": 3,
"sources": ["../../src/api/registration.js"],
"sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { select, dispatch } from '@wordpress/data';\nimport { _x } from '@wordpress/i18n';\nimport warning from '@wordpress/warning';\n\n/**\n * Internal dependencies\n */\nimport i18nBlockSchema from './i18n-block.json' with { type: 'json' };\nimport { store as blocksStore } from '../store';\nimport { unlock } from '../lock-unlock';\n\n/**\n * An icon type definition. One of a Dashicon slug, an element,\n * or a component.\n *\n * @typedef {(string|Element|Component)} WPIcon\n *\n * @see https://developer.wordpress.org/resource/dashicons/\n */\n\n/**\n * Render behavior of a block type icon; one of a Dashicon slug, an element,\n * or a component.\n *\n * @typedef {WPIcon} WPBlockTypeIconRender\n */\n\n/**\n * An object describing a normalized block type icon.\n *\n * @typedef {Object} WPBlockTypeIconDescriptor\n *\n * @property {WPBlockTypeIconRender} src Render behavior of the icon,\n * one of a Dashicon slug, an\n * element, or a component.\n * @property {string} background Optimal background hex string\n * color when displaying icon.\n * @property {string} foreground Optimal foreground hex string\n * color when displaying icon.\n * @property {string} shadowColor Optimal shadow hex string\n * color when displaying icon.\n */\n\n/**\n * Value to use to render the icon for a block type in an editor interface,\n * either a Dashicon slug, an element, a component, or an object describing\n * the icon.\n *\n * @typedef {(WPBlockTypeIconDescriptor|WPBlockTypeIconRender)} WPBlockTypeIcon\n */\n\n/**\n * Named block variation scopes.\n *\n * @typedef {'block'|'inserter'|'transform'} WPBlockVariationScope\n */\n\n/**\n * An object describing a variation defined for the block type.\n *\n * @typedef {Object} WPBlockVariation\n *\n * @property {string} name The unique and machine-readable name.\n * @property {string} title A human-readable variation title.\n * @property {string} [description] A detailed variation description.\n * @property {string} [category] Block type category classification,\n * used in search interfaces to arrange\n * block types by category.\n * @property {WPIcon} [icon] An icon helping to visualize the variation.\n * @property {boolean} [isDefault] Indicates whether the current variation is\n * the default one. Defaults to `false`.\n * @property {Object} [attributes] Values which override block attributes.\n * @property {Array[]} [innerBlocks] Initial configuration of nested blocks.\n * @property {Object} [example] Example provides structured data for\n * the block preview. You can set to\n * `undefined` to disable the preview shown\n * for the block type.\n * @property {WPBlockVariationScope[]} [scope] The list of scopes where the variation\n * is applicable. When not provided, it\n * assumes all available scopes.\n * @property {string[]} [keywords] An array of terms (which can be translated)\n * that help users discover the variation\n * while searching.\n * @property {Function|string[]} [isActive] This can be a function or an array of block attributes.\n * Function that accepts a block's attributes and the\n * variation's attributes and determines if a variation is active.\n * This function doesn't try to find a match dynamically based\n * on all block's attributes, as in many cases some attributes are irrelevant.\n * An example would be for `embed` block where we only care\n * about `providerNameSlug` attribute's value.\n * We can also use a `string[]` to tell which attributes\n * should be compared as a shorthand. Each attributes will\n * be matched and the variation will be active if all of them are matching.\n */\n\n/**\n * Defined behavior of a block type.\n *\n * @typedef {Object} WPBlockType\n *\n * @property {string} name Block type's namespaced name.\n * @property {string} title Human-readable block type label.\n * @property {string} [description] A detailed block type description.\n * @property {string} [category] Block type category classification,\n * used in search interfaces to arrange\n * block types by category.\n * @property {WPBlockTypeIcon} [icon] Block type icon.\n * @property {string[]} [keywords] Additional keywords to produce block\n * type as result in search interfaces.\n * @property {Object} [attributes] Block type attributes.\n * @property {Component} [save] Optional component describing\n * serialized markup structure of a\n * block type.\n * @property {Component} edit Component rendering an element to\n * manipulate the attributes of a block\n * in the context of an editor.\n * @property {WPBlockVariation[]} [variations] The list of block variations.\n * @property {Object} [example] Example provides structured data for\n * the block preview. When not defined\n * then no preview is shown.\n */\n\n/**\n * An object describing a Block Bindings source.\n *\n * @typedef {Object} WPBlockBindingsSource\n *\n * @property {string} name The unique and machine-readable name.\n * @property {string} [label] Human-readable label. Optional when it is defined in the server.\n * @property {Array} [usesContext] Optional array of context needed by the source only in the editor.\n * @property {Function} [getValues] Optional function to get the values from the source.\n * @property {Function} [setValues] Optional function to update multiple values connected to the source.\n * @property {Function} [canUserEditValue] Optional function to determine if the user can edit the value.\n * @property {Function} [getFieldsList] Optional function that returns fields list that will be shown in the UI.\n */\n\nfunction isObject( object ) {\n\treturn object !== null && typeof object === 'object';\n}\n\n/**\n * Sets the server side block definition of blocks.\n *\n * Ignored from documentation due to being marked as unstable.\n *\n * @ignore\n *\n * @param {Object} definitions Server-side block definitions\n */\n// eslint-disable-next-line camelcase\nexport function unstable__bootstrapServerSideBlockDefinitions( definitions ) {\n\tconst { addBootstrappedBlockType } = unlock( dispatch( blocksStore ) );\n\tfor ( const [ name, blockType ] of Object.entries( definitions ) ) {\n\t\taddBootstrappedBlockType( name, blockType );\n\t}\n}\n\n/**\n * Gets block settings from metadata loaded from `block.json` file\n *\n * @param {Object} metadata Block metadata loaded from `block.json`.\n * @param {string} metadata.textdomain Textdomain to use with translations.\n *\n * @return {Object} Block settings.\n */\nfunction getBlockSettingsFromMetadata( { textdomain, ...metadata } ) {\n\tconst allowedFields = [\n\t\t'apiVersion',\n\t\t'title',\n\t\t'category',\n\t\t'parent',\n\t\t'ancestor',\n\t\t'icon',\n\t\t'description',\n\t\t'keywords',\n\t\t'attributes',\n\t\t'providesContext',\n\t\t'usesContext',\n\t\t'selectors',\n\t\t'supports',\n\t\t'styles',\n\t\t'example',\n\t\t'variations',\n\t\t'blockHooks',\n\t\t'allowedBlocks',\n\t];\n\n\tconst settings = Object.fromEntries(\n\t\tObject.entries( metadata ).filter( ( [ key ] ) =>\n\t\t\tallowedFields.includes( key )\n\t\t)\n\t);\n\n\tif ( textdomain ) {\n\t\tObject.keys( i18nBlockSchema ).forEach( ( key ) => {\n\t\t\tif ( ! settings[ key ] ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsettings[ key ] = translateBlockSettingUsingI18nSchema(\n\t\t\t\ti18nBlockSchema[ key ],\n\t\t\t\tsettings[ key ],\n\t\t\t\ttextdomain\n\t\t\t);\n\t\t} );\n\t}\n\n\treturn settings;\n}\n\n/**\n * Registers a new block provided a unique name and an object defining its\n * behavior. Once registered, the block is made available as an option to any\n * editor interface where blocks are implemented.\n *\n * For more in-depth information on registering a custom block see the\n * [Create a block tutorial](https://developer.wordpress.org/block-editor/getting-started/create-block/).\n *\n * @param {string|Object} blockNameOrMetadata Block type name or its metadata.\n * @param {Object} settings Block settings.\n *\n * @example\n * ```js\n * import { __ } from '@wordpress/i18n';\n * import { registerBlockType } from '@wordpress/blocks'\n *\n * registerBlockType( 'namespace/block-name', {\n * title: __( 'My First Block' ),\n * edit: () => <div>{ __( 'Hello from the editor!' ) }</div>,\n * save: () => <div>Hello from the saved content!</div>,\n * } );\n * ```\n *\n * @return {WPBlockType | undefined} The block, if it has been successfully registered;\n * otherwise `undefined`.\n */\nexport function registerBlockType( blockNameOrMetadata, settings ) {\n\tconst name = isObject( blockNameOrMetadata )\n\t\t? blockNameOrMetadata.name\n\t\t: blockNameOrMetadata;\n\n\tif ( typeof name !== 'string' ) {\n\t\twarning( 'Block names must be strings.' );\n\t\treturn;\n\t}\n\n\tif ( ! /^[a-z][a-z0-9-]*\\/[a-z][a-z0-9-]*$/.test( name ) ) {\n\t\twarning(\n\t\t\t'Block names must contain a namespace prefix, include only lowercase alphanumeric characters or dashes, and start with a letter. Example: my-plugin/my-custom-block'\n\t\t);\n\t\treturn;\n\t}\n\tif ( select( blocksStore ).getBlockType( name ) ) {\n\t\twarning( 'Block \"' + name + '\" is already registered.' );\n\t\treturn;\n\t}\n\n\tconst { addBootstrappedBlockType, addUnprocessedBlockType } = unlock(\n\t\tdispatch( blocksStore )\n\t);\n\n\tif ( isObject( blockNameOrMetadata ) ) {\n\t\tconst metadata = getBlockSettingsFromMetadata( blockNameOrMetadata );\n\t\taddBootstrappedBlockType( name, metadata );\n\t}\n\n\taddUnprocessedBlockType( name, settings );\n\n\treturn select( blocksStore ).getBlockType( name );\n}\n\n/**\n * Translates block settings provided with metadata using the i18n schema.\n *\n * @param {string|string[]|Object[]} i18nSchema I18n schema for the block setting.\n * @param {string|string[]|Object[]} settingValue Value for the block setting.\n * @param {string} textdomain Textdomain to use with translations.\n *\n * @return {string|string[]|Object[]} Translated setting.\n */\nfunction translateBlockSettingUsingI18nSchema(\n\ti18nSchema,\n\tsettingValue,\n\ttextdomain\n) {\n\tif ( typeof i18nSchema === 'string' && typeof settingValue === 'string' ) {\n\t\t// eslint-disable-next-line @wordpress/i18n-no-variables, @wordpress/i18n-text-domain\n\t\treturn _x( settingValue, i18nSchema, textdomain );\n\t}\n\tif (\n\t\tArray.isArray( i18nSchema ) &&\n\t\ti18nSchema.length &&\n\t\tArray.isArray( settingValue )\n\t) {\n\t\treturn settingValue.map( ( value ) =>\n\t\t\ttranslateBlockSettingUsingI18nSchema(\n\t\t\t\ti18nSchema[ 0 ],\n\t\t\t\tvalue,\n\t\t\t\ttextdomain\n\t\t\t)\n\t\t);\n\t}\n\tif (\n\t\tisObject( i18nSchema ) &&\n\t\tObject.entries( i18nSchema ).length &&\n\t\tisObject( settingValue )\n\t) {\n\t\treturn Object.keys( settingValue ).reduce( ( accumulator, key ) => {\n\t\t\tif ( ! i18nSchema[ key ] ) {\n\t\t\t\taccumulator[ key ] = settingValue[ key ];\n\t\t\t\treturn accumulator;\n\t\t\t}\n\t\t\taccumulator[ key ] = translateBlockSettingUsingI18nSchema(\n\t\t\t\ti18nSchema[ key ],\n\t\t\t\tsettingValue[ key ],\n\t\t\t\ttextdomain\n\t\t\t);\n\t\t\treturn accumulator;\n\t\t}, {} );\n\t}\n\treturn settingValue;\n}\n\n/**\n * Registers a new block collection to group blocks in the same namespace in the inserter.\n *\n * @param {string} namespace The namespace to group blocks by in the inserter; corresponds to the block namespace.\n * @param {Object} settings The block collection settings.\n * @param {string} settings.title The title to display in the block inserter.\n * @param {Object} [settings.icon] The icon to display in the block inserter.\n *\n * @example\n * ```js\n * import { __ } from '@wordpress/i18n';\n * import { registerBlockCollection, registerBlockType } from '@wordpress/blocks';\n *\n * // Register the collection.\n * registerBlockCollection( 'my-collection', {\n * title: __( 'Custom Collection' ),\n * } );\n *\n * // Register a block in the same namespace to add it to the collection.\n * registerBlockType( 'my-collection/block-name', {\n * title: __( 'My First Block' ),\n * edit: () => <div>{ __( 'Hello from the editor!' ) }</div>,\n * save: () => <div>'Hello from the saved content!</div>,\n * } );\n * ```\n */\nexport function registerBlockCollection( namespace, { title, icon } ) {\n\tdispatch( blocksStore ).addBlockCollection( namespace, title, icon );\n}\n\n/**\n * Unregisters a block collection\n *\n * @param {string} namespace The namespace to group blocks by in the inserter; corresponds to the block namespace\n *\n * @example\n * ```js\n * import { unregisterBlockCollection } from '@wordpress/blocks';\n *\n * unregisterBlockCollection( 'my-collection' );\n * ```\n */\nexport function unregisterBlockCollection( namespace ) {\n\tdispatch( blocksStore ).removeBlockCollection( namespace );\n}\n\n/**\n * Unregisters a block.\n *\n * @param {string} name Block name.\n *\n * @example\n * ```js\n * import { __ } from '@wordpress/i18n';\n * import { unregisterBlockType } from '@wordpress/blocks';\n *\n * const ExampleComponent = () => {\n * return (\n * <Button\n * onClick={ () =>\n * unregisterBlockType( 'my-collection/block-name' )\n * }\n * >\n * { __( 'Unregister my custom block.' ) }\n * </Button>\n * );\n * };\n * ```\n *\n * @return {WPBlockType | undefined} The previous block value, if it has been successfully\n * unregistered; otherwise `undefined`.\n */\nexport function unregisterBlockType( name ) {\n\tconst oldBlock = select( blocksStore ).getBlockType( name );\n\tif ( ! oldBlock ) {\n\t\twarning( 'Block \"' + name + '\" is not registered.' );\n\t\treturn;\n\t}\n\tdispatch( blocksStore ).removeBlockTypes( name );\n\treturn oldBlock;\n}\n\n/**\n * Assigns name of block for handling non-block content.\n *\n * @param {string} blockName Block name.\n */\nexport function setFreeformContentHandlerName( blockName ) {\n\tdispatch( blocksStore ).setFreeformFallbackBlockName( blockName );\n}\n\n/**\n * Retrieves name of block handling non-block content, or undefined if no\n * handler has been defined.\n *\n * @return {?string} Block name.\n */\nexport function getFreeformContentHandlerName() {\n\treturn select( blocksStore ).getFreeformFallbackBlockName();\n}\n\n/**\n * Retrieves name of block used for handling grouping interactions.\n *\n * @return {?string} Block name.\n */\nexport function getGroupingBlockName() {\n\treturn select( blocksStore ).getGroupingBlockName();\n}\n\n/**\n * Assigns name of block handling unregistered block types.\n *\n * @param {string} blockName Block name.\n */\nexport function setUnregisteredTypeHandlerName( blockName ) {\n\tdispatch( blocksStore ).setUnregisteredFallbackBlockName( blockName );\n}\n\n/**\n * Retrieves name of block handling unregistered block types, or undefined if no\n * handler has been defined.\n *\n * @return {?string} Block name.\n */\nexport function getUnregisteredTypeHandlerName() {\n\treturn select( blocksStore ).getUnregisteredFallbackBlockName();\n}\n\n/**\n * Assigns the default block name.\n *\n * @param {string} name Block name.\n *\n * @example\n * ```js\n * import { setDefaultBlockName } from '@wordpress/blocks';\n *\n * const ExampleComponent = () => {\n *\n * return (\n * <Button onClick={ () => setDefaultBlockName( 'core/heading' ) }>\n * { __( 'Set the default block to Heading' ) }\n * </Button>\n * );\n * };\n * ```\n */\nexport function setDefaultBlockName( name ) {\n\tdispatch( blocksStore ).setDefaultBlockName( name );\n}\n\n/**\n * Assigns name of block for handling block grouping interactions.\n *\n * This function lets you select a different block to group other blocks in instead of the\n * default `core/group` block. This function must be used in a component or when the DOM is fully\n * loaded. See https://developer.wordpress.org/block-editor/reference-guides/packages/packages-dom-ready/\n *\n * @param {string} name Block name.\n *\n * @example\n * ```js\n * import { setGroupingBlockName } from '@wordpress/blocks';\n *\n * const ExampleComponent = () => {\n *\n * return (\n * <Button onClick={ () => setGroupingBlockName( 'core/columns' ) }>\n * { __( 'Wrap in columns' ) }\n * </Button>\n * );\n * };\n * ```\n */\nexport function setGroupingBlockName( name ) {\n\tdispatch( blocksStore ).setGroupingBlockName( name );\n}\n\n/**\n * Retrieves the default block name.\n *\n * @return {?string} Block name.\n */\nexport function getDefaultBlockName() {\n\treturn select( blocksStore ).getDefaultBlockName();\n}\n\n/**\n * Returns a registered block type.\n *\n * @param {string} name Block name.\n *\n * @return {?Object} Block type.\n */\nexport function getBlockType( name ) {\n\treturn select( blocksStore )?.getBlockType( name );\n}\n\n/**\n * Returns all registered blocks.\n *\n * @return {Array} Block settings.\n */\nexport function getBlockTypes() {\n\treturn select( blocksStore ).getBlockTypes();\n}\n\n/**\n * Returns the block support value for a feature, if defined.\n *\n * @param {(string|Object)} nameOrType Block name or type object\n * @param {string} feature Feature to retrieve\n * @param {*} defaultSupports Default value to return if not\n * explicitly defined\n *\n * @return {?*} Block support value\n */\nexport function getBlockSupport( nameOrType, feature, defaultSupports ) {\n\treturn select( blocksStore ).getBlockSupport(\n\t\tnameOrType,\n\t\tfeature,\n\t\tdefaultSupports\n\t);\n}\n\n/**\n * Returns true if the block defines support for a feature, or false otherwise.\n *\n * @param {(string|Object)} nameOrType Block name or type object.\n * @param {string} feature Feature to test.\n * @param {boolean} defaultSupports Whether feature is supported by\n * default if not explicitly defined.\n *\n * @return {boolean} Whether block supports feature.\n */\nexport function hasBlockSupport( nameOrType, feature, defaultSupports ) {\n\treturn select( blocksStore ).hasBlockSupport(\n\t\tnameOrType,\n\t\tfeature,\n\t\tdefaultSupports\n\t);\n}\n\n/**\n * Determines whether or not the given block is a reusable block. This is a\n * special block type that is used to point to a global block stored via the\n * API.\n *\n * @param {Object} blockOrType Block or Block Type to test.\n *\n * @return {boolean} Whether the given block is a reusable block.\n */\nexport function isReusableBlock( blockOrType ) {\n\treturn blockOrType?.name === 'core/block';\n}\n\n/**\n * Determines whether or not the given block is a template part. This is a\n * special block type that allows composing a page template out of reusable\n * design elements.\n *\n * @param {Object} blockOrType Block or Block Type to test.\n *\n * @return {boolean} Whether the given block is a template part.\n */\nexport function isTemplatePart( blockOrType ) {\n\treturn blockOrType?.name === 'core/template-part';\n}\n\n/**\n * Returns an array with the child blocks of a given block.\n *\n * @param {string} blockName Name of block (example: \u201Clatest-posts\u201D).\n *\n * @return {Array} Array of child block names.\n */\nexport const getChildBlockNames = ( blockName ) => {\n\treturn select( blocksStore ).getChildBlockNames( blockName );\n};\n\n/**\n * Returns a boolean indicating if a block has child blocks or not.\n *\n * @param {string} blockName Name of block (example: \u201Clatest-posts\u201D).\n *\n * @return {boolean} True if a block contains child blocks and false otherwise.\n */\nexport const hasChildBlocks = ( blockName ) => {\n\treturn select( blocksStore ).hasChildBlocks( blockName );\n};\n\n/**\n * Returns a boolean indicating if a block has at least one child block with inserter support.\n *\n * @param {string} blockName Block type name.\n *\n * @return {boolean} True if a block contains at least one child blocks with inserter support\n * and false otherwise.\n */\nexport const hasChildBlocksWithInserterSupport = ( blockName ) => {\n\treturn select( blocksStore ).hasChildBlocksWithInserterSupport( blockName );\n};\n\n/**\n * Registers a new block style for the given block types.\n *\n * For more information on connecting the styles with CSS\n * [the official documentation](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-styles/#styles).\n *\n * @param {string|Array} blockNames Name of blocks e.g. \u201Ccore/latest-posts\u201D or `[\"core/group\", \"core/columns\"]`.\n * @param {Object} styleVariation Object containing `name` which is the class name applied to the block and `label` which identifies the variation to the user.\n *\n * @example\n * ```js\n * import { __ } from '@wordpress/i18n';\n * import { registerBlockStyle } from '@wordpress/blocks';\n * import { Button } from '@wordpress/components';\n *\n *\n * const ExampleComponent = () => {\n * return (\n * <Button\n * onClick={ () => {\n * registerBlockStyle( 'core/quote', {\n * name: 'fancy-quote',\n * label: __( 'Fancy Quote' ),\n * } );\n * } }\n * >\n * { __( 'Add a new block style for core/quote' ) }\n * </Button>\n * );\n * };\n * ```\n */\nexport const registerBlockStyle = ( blockNames, styleVariation ) => {\n\tdispatch( blocksStore ).addBlockStyles( blockNames, styleVariation );\n};\n\n/**\n * Unregisters a block style for the given block.\n *\n * @param {string} blockName Name of block (example: \u201Ccore/latest-posts\u201D).\n * @param {string} styleVariationName Name of class applied to the block.\n *\n * @example\n * ```js\n * import { __ } from '@wordpress/i18n';\n * import { unregisterBlockStyle } from '@wordpress/blocks';\n * import { Button } from '@wordpress/components';\n *\n * const ExampleComponent = () => {\n * return (\n * <Button\n * onClick={ () => {\n * unregisterBlockStyle( 'core/quote', 'plain' );\n * } }\n * >\n * { __( 'Remove the \"Plain\" block style for core/quote' ) }\n * </Button>\n * );\n * };\n * ```\n */\nexport const unregisterBlockStyle = ( blockName, styleVariationName ) => {\n\tdispatch( blocksStore ).removeBlockStyles( blockName, styleVariationName );\n};\n\n/**\n * Returns an array with the variations of a given block type.\n * Ignored from documentation as the recommended usage is via useSelect from @wordpress/data.\n *\n * @ignore\n *\n * @param {string} blockName Name of block (example: \u201Ccore/columns\u201D).\n * @param {WPBlockVariationScope} [scope] Block variation scope name.\n *\n * @return {(WPBlockVariation[]|void)} Block variations.\n */\nexport const getBlockVariations = ( blockName, scope ) => {\n\treturn select( blocksStore ).getBlockVariations( blockName, scope );\n};\n\n/**\n * Registers a new block variation for the given block type.\n *\n * For more information on block variations see\n * [the official documentation ](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-variations/).\n *\n * @param {string} blockName Name of the block (example: \u201Ccore/columns\u201D).\n * @param {WPBlockVariation} variation Object describing a block variation.\n *\n * @example\n * ```js\n * import { __ } from '@wordpress/i18n';\n * import { registerBlockVariation } from '@wordpress/blocks';\n * import { Button } from '@wordpress/components';\n *\n * const ExampleComponent = () => {\n * return (\n * <Button\n * onClick={ () => {\n * registerBlockVariation( 'core/embed', {\n * name: 'custom',\n * title: __( 'My Custom Embed' ),\n * attributes: { providerNameSlug: 'custom' },\n * } );\n * } }\n * >\n * __( 'Add a custom variation for core/embed' ) }\n * </Button>\n * );\n * };\n * ```\n */\nexport const registerBlockVariation = ( blockName, variation ) => {\n\tif ( typeof variation.name !== 'string' ) {\n\t\twarning( 'Variation names must be unique strings.' );\n\t}\n\n\tdispatch( blocksStore ).addBlockVariations( blockName, variation );\n};\n\n/**\n * Unregisters a block variation defined for the given block type.\n *\n * @param {string} blockName Name of the block (example: \u201Ccore/columns\u201D).\n * @param {string} variationName Name of the variation defined for the block.\n *\n * @example\n * ```js\n * import { __ } from '@wordpress/i18n';\n * import { unregisterBlockVariation } from '@wordpress/blocks';\n * import { Button } from '@wordpress/components';\n *\n * const ExampleComponent = () => {\n * return (\n * <Button\n * onClick={ () => {\n * unregisterBlockVariation( 'core/embed', 'youtube' );\n * } }\n * >\n * { __( 'Remove the YouTube variation from core/embed' ) }\n * </Button>\n * );\n * };\n * ```\n */\nexport const unregisterBlockVariation = ( blockName, variationName ) => {\n\tdispatch( blocksStore ).removeBlockVariations( blockName, variationName );\n};\n\n/**\n * Registers a new block bindings source with an object defining its\n * behavior. Once registered, the source is available to be connected\n * to the supported block attributes.\n *\n * @since 6.7.0 Introduced in WordPress core.\n *\n * @param {WPBlockBindingsSource} source Object describing a block bindings source.\n *\n * @example\n * ```js\n * import { _x } from '@wordpress/i18n';\n * import { registerBlockBindingsSource } from '@wordpress/blocks'\n *\n * registerBlockBindingsSource( {\n * name: 'plugin/my-custom-source',\n * label: _x( 'My Custom Source', 'block bindings source' ),\n * usesContext: [ 'postType' ],\n * getValues: getSourceValues,\n * setValues: updateMyCustomValuesInBatch,\n * canUserEditValue: () => true,\n * } );\n * ```\n */\nexport const registerBlockBindingsSource = ( source ) => {\n\tconst {\n\t\tname,\n\t\tlabel,\n\t\tusesContext,\n\t\tgetValues,\n\t\tsetValues,\n\t\tcanUserEditValue,\n\t\tgetFieldsList,\n\t} = source;\n\n\tconst existingSource = unlock(\n\t\tselect( blocksStore )\n\t).getBlockBindingsSource( name );\n\n\t/*\n\t * Check if the source has been already registered on the client.\n\t * If any property expected to be \"client-only\" is defined, return a warning.\n\t */\n\tconst serverProps = [ 'label', 'usesContext' ];\n\tfor ( const prop in existingSource ) {\n\t\tif ( ! serverProps.includes( prop ) && existingSource[ prop ] ) {\n\t\t\twarning(\n\t\t\t\t'Block bindings source \"' + name + '\" is already registered.'\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t}\n\n\t// Check the `name` property is correct.\n\tif ( ! name ) {\n\t\twarning( 'Block bindings source must contain a name.' );\n\t\treturn;\n\t}\n\n\tif ( typeof name !== 'string' ) {\n\t\twarning( 'Block bindings source name must be a string.' );\n\t\treturn;\n\t}\n\n\tif ( /[A-Z]+/.test( name ) ) {\n\t\twarning(\n\t\t\t'Block bindings source name must not contain uppercase characters.'\n\t\t);\n\t\treturn;\n\t}\n\n\tif ( ! /^[a-z0-9/-]+$/.test( name ) ) {\n\t\twarning(\n\t\t\t'Block bindings source name must contain only valid characters: lowercase characters, hyphens, or digits. Example: my-plugin/my-custom-source.'\n\t\t);\n\t\treturn;\n\t}\n\n\tif ( ! /^[a-z0-9-]+\\/[a-z0-9-]+$/.test( name ) ) {\n\t\twarning(\n\t\t\t'Block bindings source name must contain a namespace and valid characters. Example: my-plugin/my-custom-source.'\n\t\t);\n\t\treturn;\n\t}\n\n\t// Check the `label` property is correct.\n\n\tif ( ! label && ! existingSource?.label ) {\n\t\twarning( 'Block bindings source must contain a label.' );\n\t\treturn;\n\t}\n\n\tif ( label && typeof label !== 'string' ) {\n\t\twarning( 'Block bindings source label must be a string.' );\n\t\treturn;\n\t}\n\n\tif ( label && existingSource?.label && label !== existingSource?.label ) {\n\t\twarning( 'Block bindings \"' + name + '\" source label was overridden.' );\n\t}\n\n\t// Check the `usesContext` property is correct.\n\tif ( usesContext && ! Array.isArray( usesContext ) ) {\n\t\twarning( 'Block bindings source usesContext must be an array.' );\n\t\treturn;\n\t}\n\n\t// Check the `getValues` property is correct.\n\tif ( getValues && typeof getValues !== 'function' ) {\n\t\twarning( 'Block bindings source getValues must be a function.' );\n\t\treturn;\n\t}\n\n\t// Check the `setValues` property is correct.\n\tif ( setValues && typeof setValues !== 'function' ) {\n\t\twarning( 'Block bindings source setValues must be a function.' );\n\t\treturn;\n\t}\n\n\t// Check the `canUserEditValue` property is correct.\n\tif ( canUserEditValue && typeof canUserEditValue !== 'function' ) {\n\t\twarning( 'Block bindings source canUserEditValue must be a function.' );\n\t\treturn;\n\t}\n\n\t// Check the `getFieldsList` property is correct.\n\tif ( getFieldsList && typeof getFieldsList !== 'function' ) {\n\t\twarning( 'Block bindings source getFieldsList must be a function.' );\n\t\treturn;\n\t}\n\n\treturn unlock( dispatch( blocksStore ) ).addBlockBindingsSource( source );\n};\n\n/**\n * Unregisters a block bindings source by providing its name.\n *\n * @since 6.7.0 Introduced in WordPress core.\n *\n * @param {string} name The name of the block bindings source to unregister.\n *\n * @example\n * ```js\n * import { unregisterBlockBindingsSource } from '@wordpress/blocks';\n *\n * unregisterBlockBindingsSource( 'plugin/my-custom-source' );\n * ```\n */\nexport function unregisterBlockBindingsSource( name ) {\n\tconst oldSource = getBlockBindingsSource( name );\n\tif ( ! oldSource ) {\n\t\twarning( 'Block bindings source \"' + name + '\" is not registered.' );\n\t\treturn;\n\t}\n\tunlock( dispatch( blocksStore ) ).removeBlockBindingsSource( name );\n}\n\n/**\n * Returns a registered block bindings source by its name.\n *\n * @since 6.7.0 Introduced in WordPress core.\n *\n * @param {string} name Block bindings source name.\n *\n * @return {?Object} Block bindings source.\n */\nexport function getBlockBindingsSource( name ) {\n\treturn unlock( select( blocksStore ) ).getBlockBindingsSource( name );\n}\n\n/**\n * Returns all registered block bindings sources.\n *\n * @since 6.7.0 Introduced in WordPress core.\n *\n * @return {Array} Block bindings sources.\n */\nexport function getBlockBindingsSources() {\n\treturn unlock( select( blocksStore ) ).getAllBlockBindingsSources();\n}\n"],
"mappings": ";AAGA,SAAS,QAAQ,gBAAgB;AACjC,SAAS,UAAU;AACnB,OAAO,aAAa;AAKpB,OAAO,qBAAqB;AAC5B,SAAS,SAAS,mBAAmB;AACrC,SAAS,cAAc;AA+HvB,SAAS,SAAU,QAAS;AAC3B,SAAO,WAAW,QAAQ,OAAO,WAAW;AAC7C;AAYO,SAAS,8CAA+C,aAAc;AAC5E,QAAM,EAAE,yBAAyB,IAAI,OAAQ,SAAU,WAAY,CAAE;AACrE,aAAY,CAAE,MAAM,SAAU,KAAK,OAAO,QAAS,WAAY,GAAI;AAClE,6BAA0B,MAAM,SAAU;AAAA,EAC3C;AACD;AAUA,SAAS,6BAA8B,EAAE,YAAY,GAAG,SAAS,GAAI;AACpE,QAAM,gBAAgB;AAAA,IACrB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD;AAEA,QAAM,WAAW,OAAO;AAAA,IACvB,OAAO,QAAS,QAAS,EAAE;AAAA,MAAQ,CAAE,CAAE,GAAI,MAC1C,cAAc,SAAU,GAAI;AAAA,IAC7B;AAAA,EACD;AAEA,MAAK,YAAa;AACjB,WAAO,KAAM,eAAgB,EAAE,QAAS,CAAE,QAAS;AAClD,UAAK,CAAE,SAAU,GAAI,GAAI;AACxB;AAAA,MACD;AACA,eAAU,GAAI,IAAI;AAAA,QACjB,gBAAiB,GAAI;AAAA,QACrB,SAAU,GAAI;AAAA,QACd;AAAA,MACD;AAAA,IACD,CAAE;AAAA,EACH;AAEA,SAAO;AACR;AA4BO,SAAS,kBAAmB,qBAAqB,UAAW;AAClE,QAAM,OAAO,SAAU,mBAAoB,IACxC,oBAAoB,OACpB;AAEH,MAAK,OAAO,SAAS,UAAW;AAC/B,YAAS,8BAA+B;AACxC;AAAA,EACD;AAEA,MAAK,CAAE,qCAAqC,KAAM,IAAK,GAAI;AAC1D;AAAA,MACC;AAAA,IACD;AACA;AAAA,EACD;AACA,MAAK,OAAQ,WAAY,EAAE,aAAc,IAAK,GAAI;AACjD,YAAS,YAAY,OAAO,0BAA2B;AACvD;AAAA,EACD;AAEA,QAAM,EAAE,0BAA0B,wBAAwB,IAAI;AAAA,IAC7D,SAAU,WAAY;AAAA,EACvB;AAEA,MAAK,SAAU,mBAAoB,GAAI;AACtC,UAAM,WAAW,6BAA8B,mBAAoB;AACnE,6BAA0B,MAAM,QAAS;AAAA,EAC1C;AAEA,0BAAyB,MAAM,QAAS;AAExC,SAAO,OAAQ,WAAY,EAAE,aAAc,IAAK;AACjD;AAWA,SAAS,qCACR,YACA,cACA,YACC;AACD,MAAK,OAAO,eAAe,YAAY,OAAO,iBAAiB,UAAW;AAEzE,WAAO,GAAI,cAAc,YAAY,UAAW;AAAA,EACjD;AACA,MACC,MAAM,QAAS,UAAW,KAC1B,WAAW,UACX,MAAM,QAAS,YAAa,GAC3B;AACD,WAAO,aAAa;AAAA,MAAK,CAAE,UAC1B;AAAA,QACC,WAAY,CAAE;AAAA,QACd;AAAA,QACA;AAAA,MACD;AAAA,IACD;AAAA,EACD;AACA,MACC,SAAU,UAAW,KACrB,OAAO,QAAS,UAAW,EAAE,UAC7B,SAAU,YAAa,GACtB;AACD,WAAO,OAAO,KAAM,YAAa,EAAE,OAAQ,CAAE,aAAa,QAAS;AAClE,UAAK,CAAE,WAAY,GAAI,GAAI;AAC1B,oBAAa,GAAI,IAAI,aAAc,GAAI;AACvC,eAAO;AAAA,MACR;AACA,kBAAa,GAAI,IAAI;AAAA,QACpB,WAAY,GAAI;AAAA,QAChB,aAAc,GAAI;AAAA,QAClB;AAAA,MACD;AACA,aAAO;AAAA,IACR,GAAG,CAAC,CAAE;AAAA,EACP;AACA,SAAO;AACR;AA4BO,SAAS,wBAAyB,WAAW,EAAE,OAAO,KAAK,GAAI;AACrE,WAAU,WAAY,EAAE,mBAAoB,WAAW,OAAO,IAAK;AACpE;AAcO,SAAS,0BAA2B,WAAY;AACtD,WAAU,WAAY,EAAE,sBAAuB,SAAU;AAC1D;AA4BO,SAAS,oBAAqB,MAAO;AAC3C,QAAM,WAAW,OAAQ,WAAY,EAAE,aAAc,IAAK;AAC1D,MAAK,CAAE,UAAW;AACjB,YAAS,YAAY,OAAO,sBAAuB;AACnD;AAAA,EACD;AACA,WAAU,WAAY,EAAE,iBAAkB,IAAK;AAC/C,SAAO;AACR;AAOO,SAAS,8BAA+B,WAAY;AAC1D,WAAU,WAAY,EAAE,6BAA8B,SAAU;AACjE;AAQO,SAAS,gCAAgC;AAC/C,SAAO,OAAQ,WAAY,EAAE,6BAA6B;AAC3D;AAOO,SAAS,uBAAuB;AACtC,SAAO,OAAQ,WAAY,EAAE,qBAAqB;AACnD;AAOO,SAAS,+BAAgC,WAAY;AAC3D,WAAU,WAAY,EAAE,iCAAkC,SAAU;AACrE;AAQO,SAAS,iCAAiC;AAChD,SAAO,OAAQ,WAAY,EAAE,iCAAiC;AAC/D;AAqBO,SAAS,oBAAqB,MAAO;AAC3C,WAAU,WAAY,EAAE,oBAAqB,IAAK;AACnD;AAyBO,SAAS,qBAAsB,MAAO;AAC5C,WAAU,WAAY,EAAE,qBAAsB,IAAK;AACpD;AAOO,SAAS,sBAAsB;AACrC,SAAO,OAAQ,WAAY,EAAE,oBAAoB;AAClD;AASO,SAAS,aAAc,MAAO;AACpC,SAAO,OAAQ,WAAY,GAAG,aAAc,IAAK;AAClD;AAOO,SAAS,gBAAgB;AAC/B,SAAO,OAAQ,WAAY,EAAE,cAAc;AAC5C;AAYO,SAAS,gBAAiB,YAAY,SAAS,iBAAkB;AACvE,SAAO,OAAQ,WAAY,EAAE;AAAA,IAC5B;AAAA,IACA;AAAA,IACA;AAAA,EACD;AACD;AAYO,SAAS,gBAAiB,YAAY,SAAS,iBAAkB;AACvE,SAAO,OAAQ,WAAY,EAAE;AAAA,IAC5B;AAAA,IACA;AAAA,IACA;AAAA,EACD;AACD;AAWO,SAAS,gBAAiB,aAAc;AAC9C,SAAO,aAAa,SAAS;AAC9B;AAWO,SAAS,eAAgB,aAAc;AAC7C,SAAO,aAAa,SAAS;AAC9B;AASO,IAAM,qBAAqB,CAAE,cAAe;AAClD,SAAO,OAAQ,WAAY,EAAE,mBAAoB,SAAU;AAC5D;AASO,IAAM,iBAAiB,CAAE,cAAe;AAC9C,SAAO,OAAQ,WAAY,EAAE,eAAgB,SAAU;AACxD;AAUO,IAAM,oCAAoC,CAAE,cAAe;AACjE,SAAO,OAAQ,WAAY,EAAE,kCAAmC,SAAU;AAC3E;AAkCO,IAAM,qBAAqB,CAAE,YAAY,mBAAoB;AACnE,WAAU,WAAY,EAAE,eAAgB,YAAY,cAAe;AACpE;AA2BO,IAAM,uBAAuB,CAAE,WAAW,uBAAwB;AACxE,WAAU,WAAY,EAAE,kBAAmB,WAAW,kBAAmB;AAC1E;AAaO,IAAM,qBAAqB,CAAE,WAAW,UAAW;AACzD,SAAO,OAAQ,WAAY,EAAE,mBAAoB,WAAW,KAAM;AACnE;AAkCO,IAAM,yBAAyB,CAAE,WAAW,cAAe;AACjE,MAAK,OAAO,UAAU,SAAS,UAAW;AACzC,YAAS,yCAA0C;AAAA,EACpD;AAEA,WAAU,WAAY,EAAE,mBAAoB,WAAW,SAAU;AAClE;AA2BO,IAAM,2BAA2B,CAAE,WAAW,kBAAmB;AACvE,WAAU,WAAY,EAAE,sBAAuB,WAAW,aAAc;AACzE;AA0BO,IAAM,8BAA8B,CAAE,WAAY;AACxD,QAAM;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD,IAAI;AAEJ,QAAM,iBAAiB;AAAA,IACtB,OAAQ,WAAY;AAAA,EACrB,EAAE,uBAAwB,IAAK;AAM/B,QAAM,cAAc,CAAE,SAAS,aAAc;AAC7C,aAAY,QAAQ,gBAAiB;AACpC,QAAK,CAAE,YAAY,SAAU,IAAK,KAAK,eAAgB,IAAK,GAAI;AAC/D;AAAA,QACC,4BAA4B,OAAO;AAAA,MACpC;AACA;AAAA,IACD;AAAA,EACD;AAGA,MAAK,CAAE,MAAO;AACb,YAAS,4CAA6C;AACtD;AAAA,EACD;AAEA,MAAK,OAAO,SAAS,UAAW;AAC/B,YAAS,8CAA+C;AACxD;AAAA,EACD;AAEA,MAAK,SAAS,KAAM,IAAK,GAAI;AAC5B;AAAA,MACC;AAAA,IACD;AACA;AAAA,EACD;AAEA,MAAK,CAAE,gBAAgB,KAAM,IAAK,GAAI;AACrC;AAAA,MACC;AAAA,IACD;AACA;AAAA,EACD;AAEA,MAAK,CAAE,2BAA2B,KAAM,IAAK,GAAI;AAChD;AAAA,MACC;AAAA,IACD;AACA;AAAA,EACD;AAIA,MAAK,CAAE,SAAS,CAAE,gBAAgB,OAAQ;AACzC,YAAS,6CAA8C;AACvD;AAAA,EACD;AAEA,MAAK,SAAS,OAAO,UAAU,UAAW;AACzC,YAAS,+CAAgD;AACzD;AAAA,EACD;AAEA,MAAK,SAAS,gBAAgB,SAAS,UAAU,gBAAgB,OAAQ;AACxE,YAAS,qBAAqB,OAAO,gCAAiC;AAAA,EACvE;AAGA,MAAK,eAAe,CAAE,MAAM,QAAS,WAAY,GAAI;AACpD,YAAS,qDAAsD;AAC/D;AAAA,EACD;AAGA,MAAK,aAAa,OAAO,cAAc,YAAa;AACnD,YAAS,qDAAsD;AAC/D;AAAA,EACD;AAGA,MAAK,aAAa,OAAO,cAAc,YAAa;AACnD,YAAS,qDAAsD;AAC/D;AAAA,EACD;AAGA,MAAK,oBAAoB,OAAO,qBAAqB,YAAa;AACjE,YAAS,4DAA6D;AACtE;AAAA,EACD;AAGA,MAAK,iBAAiB,OAAO,kBAAkB,YAAa;AAC3D,YAAS,yDAA0D;AACnE;AAAA,EACD;AAEA,SAAO,OAAQ,SAAU,WAAY,CAAE,EAAE,uBAAwB,MAAO;AACzE;AAgBO,SAAS,8BAA+B,MAAO;AACrD,QAAM,YAAY,uBAAwB,IAAK;AAC/C,MAAK,CAAE,WAAY;AAClB,YAAS,4BAA4B,OAAO,sBAAuB;AACnE;AAAA,EACD;AACA,SAAQ,SAAU,WAAY,CAAE,EAAE,0BAA2B,IAAK;AACnE;AAWO,SAAS,uBAAwB,MAAO;AAC9C,SAAO,OAAQ,OAAQ,WAAY,CAAE,EAAE,uBAAwB,IAAK;AACrE;AASO,SAAS,0BAA0B;AACzC,SAAO,OAAQ,OAAQ,WAAY,CAAE,EAAE,2BAA2B;AACnE;",
"names": []
}