diff --git a/docs/reference-guides/data/data-core-blocks.md b/docs/reference-guides/data/data-core-blocks.md index 084c9c1d7a5fb..7470826294720 100644 --- a/docs/reference-guides/data/data-core-blocks.md +++ b/docs/reference-guides/data/data-core-blocks.md @@ -45,14 +45,14 @@ const ExampleComponent = () => { _Parameters_ -- _state_ `Object`: Data state. +- _state_ `BlockStoreState`: Data state. - _blockName_ `string`: Name of block (example: “core/columns”). -- _attributes_ `Object`: Block attributes used to determine active variation. -- _scope_ `[WPBlockVariationScope]`: Block variation scope name. +- _attributes_ `BlockAttributes`: Block attributes used to determine active variation. +- _scope_ `BlockVariationScope=`: Block variation scope name. _Returns_ -- `(WPBlockVariation|undefined)`: Active block variation. +- `BlockVariation|undefined`: Active block variation. ### getBlockStyles @@ -83,12 +83,12 @@ const ExampleComponent = () => { _Parameters_ -- _state_ `Object`: Data state. +- _state_ `BlockStoreState`: Data state. - _name_ `string`: Block type name. _Returns_ -- `Array?`: Block Styles. +- `BlockStyle[]|undefined`: Block Styles. ### getBlockSupport @@ -121,14 +121,14 @@ const ExampleComponent = () => { _Parameters_ -- _state_ `Object`: Data state. -- _nameOrType_ `(string|Object)`: Block name or type object -- _feature_ `Array|string`: Feature to retrieve +- _state_ `BlockStoreState`: Data state. +- _nameOrType_ `string|BlockType`: Block name or type object +- _feature_ `string|string[]`: Feature to retrieve - _defaultSupports_ `*`: Default value to return if not explicitly defined _Returns_ -- `?*`: Block support value +- `*`: Block support value ### getBlockType @@ -167,12 +167,12 @@ const ExampleComponent = () => { _Parameters_ -- _state_ `Object`: Data state. +- _state_ `BlockStoreState`: Data state. - _name_ `string`: Block type name. _Returns_ -- `Object?`: Block Type. +- `BlockType|undefined`: Block Type. ### getBlockTypes @@ -202,11 +202,11 @@ const ExampleComponent = () => { _Parameters_ -- _state_ `Object`: Data state. +- _state_ `BlockStoreState`: Data state. _Returns_ -- `Array`: Block Types. +- `BlockType[]`: Block Types. ### getBlockVariations @@ -238,13 +238,13 @@ const ExampleComponent = () => { _Parameters_ -- _state_ `Object`: Data state. +- _state_ `BlockStoreState`: Data state. - _blockName_ `string`: Block type name. -- _scope_ `[WPBlockVariationScope]`: Block variation scope name. +- _scope_ `BlockVariationScope=`: Block variation scope name. _Returns_ -- `(WPBlockVariation[]|void)`: Block variations. +- `(BlockVariation[]|undefined) & EnhancedSelector`: Block variations. ### getCategories @@ -274,11 +274,11 @@ const ExampleComponent = () => { _Parameters_ -- _state_ `Object`: Data state. +- _state_ `BlockStoreState`: Data state. _Returns_ -- `WPBlockCategory[]`: Categories list. +- `BlockCategory[]`: Categories list. ### getChildBlockNames @@ -310,12 +310,12 @@ const ExampleComponent = () => { _Parameters_ -- _state_ `Object`: Data state. +- _state_ `BlockStoreState`: Data state. - _blockName_ `string`: Block type name. _Returns_ -- `Array`: Array of child block names. +- `string[]`: Array of child block names. ### getCollections @@ -346,11 +346,11 @@ const ExampleComponent = () => { _Parameters_ -- _state_ `Object`: Data state. +- _state_ `BlockStoreState`: Data state. _Returns_ -- `Object`: Collections list. +- `BlockCollection[]`: Collections list. ### getDefaultBlockName @@ -381,11 +381,11 @@ const ExampleComponent = () => { _Parameters_ -- _state_ `Object`: Data state. +- _state_ `BlockStoreState`: Data state. _Returns_ -- `string?`: Default block name. +- `string|undefined`: Default block name. ### getDefaultBlockVariation @@ -420,13 +420,13 @@ const ExampleComponent = () => { _Parameters_ -- _state_ `Object`: Data state. +- _state_ `BlockStoreState`: Data state. - _blockName_ `string`: Block type name. -- _scope_ `[WPBlockVariationScope]`: Block variation scope name. +- _scope_ `BlockVariationScope=`: Block variation scope name. _Returns_ -- `?WPBlockVariation`: The default block variation. +- `BlockVariation|undefined`: The default block variation. ### getFreeformFallbackBlockName @@ -460,11 +460,11 @@ const ExampleComponent = () => { _Parameters_ -- _state_ `Object`: Data state. +- _state_ `BlockStoreState`: Data state. _Returns_ -- `string?`: Name of the block for handling non-block content. +- `string|undefined`: Name of the block for handling non-block content. ### getGroupingBlockName @@ -498,11 +498,11 @@ const ExampleComponent = () => { _Parameters_ -- _state_ `Object`: Data state. +- _state_ `BlockStoreState`: Data state. _Returns_ -- `string?`: Name of the block for handling the grouping of blocks. +- `string|undefined`: Name of the block for handling the grouping of blocks. ### getUnregisteredFallbackBlockName @@ -536,11 +536,11 @@ const ExampleComponent = () => { _Parameters_ -- _state_ `Object`: Data state. +- _state_ `BlockStoreState`: Data state. _Returns_ -- `string?`: Name of the block for handling unregistered blocks. +- `string|undefined`: Name of the block for handling unregistered blocks. ### hasBlockSupport @@ -572,8 +572,8 @@ const ExampleComponent = () => { _Parameters_ -- _state_ `Object`: Data state. -- _nameOrType_ `(string|Object)`: Block name or type object. +- _state_ `BlockStoreState`: Data state. +- _nameOrType_ `string|BlockType`: Block name or type object. - _feature_ `string`: Feature to test. - _defaultSupports_ `boolean`: Whether feature is supported by default if not explicitly defined. @@ -611,7 +611,7 @@ const ExampleComponent = () => { _Parameters_ -- _state_ `Object`: Data state. +- _state_ `BlockStoreState`: Data state. - _blockName_ `string`: Block type name. _Returns_ @@ -653,7 +653,7 @@ const ExampleComponent = () => { _Parameters_ -- _state_ `Object`: Data state. +- _state_ `BlockStoreState`: Data state. - _blockName_ `string`: Block type name. _Returns_ @@ -696,13 +696,13 @@ const ExampleComponent = () => { _Parameters_ -- _state_ `Object`: Blocks state. -- _nameOrType_ `(string|Object)`: Block name or type object. +- _state_ `BlockStoreState`: Blocks state. +- _nameOrType_ `string|BlockType`: Block name or type object. - _searchTerm_ `string`: Search term by which to filter. _Returns_ -- `Object[]`: Whether block type matches search term. +- `boolean`: Whether block type matches search term. diff --git a/packages/block-editor/tsconfig.json b/packages/block-editor/tsconfig.json index ed81774f6071c..40a42806ddc12 100644 --- a/packages/block-editor/tsconfig.json +++ b/packages/block-editor/tsconfig.json @@ -8,6 +8,7 @@ { "path": "../a11y" }, { "path": "../api-fetch" }, { "path": "../blob" }, + { "path": "../blocks" }, { "path": "../components" }, { "path": "../compose" }, { "path": "../data" }, diff --git a/packages/block-library/tsconfig.json b/packages/block-library/tsconfig.json index a5f01298a8fad..a7d529110d75e 100644 --- a/packages/block-library/tsconfig.json +++ b/packages/block-library/tsconfig.json @@ -12,6 +12,7 @@ { "path": "../autop" }, { "path": "../blob" }, { "path": "../block-editor" }, + { "path": "../blocks" }, { "path": "../components" }, { "path": "../compose" }, { "path": "../core-data" }, diff --git a/packages/blocks/README.md b/packages/blocks/README.md index 8e6fdc9d900db..9191e424691c3 100644 --- a/packages/blocks/README.md +++ b/packages/blocks/README.md @@ -28,9 +28,9 @@ Given a block object, returns a copy of the block object, optionally merging new _Parameters_ -- _block_ `Object`: Block instance. -- _mergeAttributes_ `Object`: Block attributes. -- _newInnerBlocks_ `?Array`: Nested blocks. +- _block_ `Block`: Block instance. +- _mergeAttributes_ `BlockAttributes`: Block attributes. +- _newInnerBlocks_ `Block[]=`: Nested blocks. _Returns_ @@ -43,12 +43,12 @@ Returns a block object given its type and attributes. _Parameters_ - _name_ `string`: Block name. -- _attributes_ `Object`: Block attributes. -- _innerBlocks_ `?Array`: Nested blocks. +- _attributes_ `BlockAttributes`: Block attributes. +- _innerBlocks_ `Block[]=`: Nested blocks. _Returns_ -- `Object`: Block object. +- `Block`: Block object. ### createBlocksFromInnerBlocksTemplate @@ -56,11 +56,11 @@ Given an array of InnerBlocks templates or Block Objects, returns an array of cr _Parameters_ -- _innerBlocksOrTemplate_ `Array`: Nested blocks or InnerBlocks templates. +- _innerBlocksOrTemplate_ `Array`: Nested blocks or InnerBlocks templates. _Returns_ -- `Object[]`: Array of Block objects. +- `Block[]`: Array of Block objects. ### doBlocksMatchTemplate @@ -68,8 +68,8 @@ Checks whether a list of blocks matches a template by comparing the block names. _Parameters_ -- _blocks_ `Array`: Block list. -- _template_ `Array`: Block template. +- _blocks_ `Block[]`: Block list. +- _template_ `InnerBlockTemplate[]`: Block template. _Returns_ @@ -81,12 +81,12 @@ Given an array of transforms, returns the highest-priority transform where the p _Parameters_ -- _transforms_ `Object[]`: Transforms to search. -- _predicate_ `Function`: Function returning true on matching transform. +- _transforms_ `Transform[]`: Transforms to search. +- _predicate_ `(transform: Transform) => boolean`: Function returning true on matching transform. _Returns_ -- `?Object`: Highest-priority transform candidate. +- `Transform|undefined`: Highest-priority transform candidate. ### getBlockAttributes @@ -94,13 +94,13 @@ Returns the block attributes of a registered block node given its type. _Parameters_ -- _blockTypeOrName_ `string|Object`: Block type or name. +- _blockTypeOrName_ `T|string`: Block type or name. - _innerHTML_ `string|Node`: Raw block content. -- _attributes_ `?Object`: Known block attributes (from delimiters). +- _attributes_ `Partial=`: Known block attributes (from delimiters). _Returns_ -- `Object`: All block attributes. +- `T extends import('../../types').BlockType> ? U : Record`: All block attributes. ### getBlockContent @@ -108,7 +108,7 @@ Given a block object, returns the Block's Inner HTML markup. _Parameters_ -- _block_ `Object`: Block instance. +- _block_ `Block`: Block instance. _Returns_ @@ -133,11 +133,11 @@ Create a block object from the example API. _Parameters_ - _name_ `string`: -- _example_ `Object`: +- _example_ `Block`: _Returns_ -- `Object`: block. +- `Block`: block. ### getBlockMenuDefaultClassName @@ -157,13 +157,13 @@ Returns the block support value for a feature, if defined. _Parameters_ -- _nameOrType_ `(string|Object)`: Block name or type object -- _feature_ `string`: Feature to retrieve +- _nameOrType_ `string|BlockType`: Block name or type object +- _feature_ `keyof BlockSupports`: Feature to retrieve - _defaultSupports_ `*`: Default value to return if not explicitly defined _Returns_ -- `?*`: Block support value +- `*`: Block support value ### getBlockTransforms @@ -171,12 +171,12 @@ Returns normal block transforms for a given transform direction, optionally for _Parameters_ -- _direction_ `string`: Transform direction ("to", "from"). -- _blockTypeOrName_ `string|Object`: Block type or name. +- _direction_ `'from'|'to'`: Transform direction ("to", "from"). +- _blockTypeOrName_ `BlockType|string`: Block type or name. _Returns_ -- `Array`: Block transforms for direction. +- `Transform[]`: Block transforms for direction. ### getBlockType @@ -188,7 +188,7 @@ _Parameters_ _Returns_ -- `?Object`: Block type. +- `BlockType|undefined`: Block type. ### getBlockTypes @@ -196,7 +196,7 @@ Returns all registered blocks. _Returns_ -- `Array`: Block settings. +- `BlockType[]`: Block settings. ### getChildBlockNames @@ -208,7 +208,7 @@ _Parameters_ _Returns_ -- `Array`: Array of child block names. +- `string[]`: Array of child block names. ### getDefaultBlockName @@ -216,7 +216,7 @@ Retrieves the default block name. _Returns_ -- `?string`: Block name. +- `string|undefined`: Block name. ### getFreeformContentHandlerName @@ -224,7 +224,7 @@ Retrieves name of block handling non-block content, or undefined if no handler h _Returns_ -- `?string`: Block name. +- `string|undefined`: Block name. ### getGroupingBlockName @@ -232,7 +232,7 @@ Retrieves name of block used for handling grouping interactions. _Returns_ -- `?string`: Block name. +- `string|undefined`: Block name. ### getPhrasingContentSchema @@ -244,11 +244,11 @@ Returns an array of block types that the set of blocks received as argument can _Parameters_ -- _blocks_ `Array`: Blocks array. +- _blocks_ `Block[]`: Blocks array. _Returns_ -- `Array`: Block types that the blocks argument can be transformed to. +- `BlockType[]`: Block types that the blocks argument can be transformed to. ### getSaveContent @@ -256,9 +256,9 @@ Given a block type containing a save render implementation and attributes, retur _Parameters_ -- _blockTypeOrName_ `string|Object`: Block type or name. -- _attributes_ `Object`: Block attributes. -- _innerBlocks_ `?Array`: Nested blocks. +- _blockTypeOrName_ `BlockType|string`: Block type or name. +- _attributes_ `BlockAttributes`: Block attributes. +- _innerBlocks_ `Block[]=`: Nested blocks. _Returns_ @@ -270,13 +270,13 @@ Given a block type containing a save render implementation and attributes, retur _Parameters_ -- _blockTypeOrName_ `string|Object`: Block type or name. -- _attributes_ `Object`: Block attributes. -- _innerBlocks_ `?Array`: Nested blocks. +- _blockTypeOrName_ `BlockType|string`: Block type or name. +- _attributes_ `BlockAttributes`: Block attributes. +- _innerBlocks_ `Block[]=`: Nested blocks. _Returns_ -- `Object|string`: Save element or raw HTML string. +- `BlockSaveResult|string`: Save element or raw HTML string. ### getUnregisteredTypeHandlerName @@ -284,7 +284,7 @@ Retrieves name of block handling unregistered block types, or undefined if no ha _Returns_ -- `?string`: Block name. +- `string|undefined`: Block name. ### hasBlockSupport @@ -292,8 +292,8 @@ Returns true if the block defines support for a feature, or false otherwise. _Parameters_ -- _nameOrType_ `(string|Object)`: Block name or type object. -- _feature_ `string`: Feature to test. +- _nameOrType_ `string|BlockType`: Block name or type object. +- _feature_ `keyof BlockSupports`: Feature to test. - _defaultSupports_ `boolean`: Whether feature is supported by default if not explicitly defined. _Returns_ @@ -330,7 +330,7 @@ Determines whether or not the given block is a reusable block. This is a special _Parameters_ -- _blockOrType_ `Object`: Block or Block Type to test. +- _blockOrType_ `BlockType|Block`: Block or Block Type to test. _Returns_ @@ -342,7 +342,7 @@ Determines whether or not the given block is a template part. This is a special _Parameters_ -- _blockOrType_ `Object`: Block or Block Type to test. +- _blockOrType_ `Block|BlockType`: Block or Block Type to test. _Returns_ @@ -354,7 +354,7 @@ Determines whether the block's attributes are equal to the default attributes wh _Parameters_ -- _block_ `WPBlock`: Block Object +- _block_ `Block`: Block Object _Returns_ @@ -366,7 +366,7 @@ Determines whether the block is a default block and its attributes are equal to _Parameters_ -- _block_ `WPBlock`: Block Object +- _block_ `Block`: Block Object _Returns_ @@ -382,8 +382,8 @@ Logs to console in development environments when invalid. _Parameters_ -- _blockTypeOrName_ `string|Object`: Block type. -- _attributes_ `Object`: Parsed block attributes. +- _blockTypeOrName_ `BlockType|string`: Block type. +- _attributes_ `BlockAttributes`: Parsed block attributes. - _originalBlockContent_ `string`: Original block content. _Returns_ @@ -400,7 +400,7 @@ _Parameters_ _Returns_ -- `boolean`: True if the parameter is a valid icon and false otherwise. +- `icon is BlockIconRenderer`: True if the parameter is a valid icon and false otherwise. ### normalizeIconObject @@ -408,11 +408,11 @@ Function that receives an icon as set by the blocks during the registration and _Parameters_ -- _icon_ `WPBlockTypeIconRender`: Render behavior of a block type icon; one of a Dashicon slug, an element, or a component. +- _icon_ `BlockIcon`: Render behavior of a block type icon; one of a Dashicon slug, an element, or a component. _Returns_ -- `WPBlockTypeIconDescriptor`: Object describing the icon. +- `BlockIconNormalized`: Object describing the icon. ### parse @@ -427,11 +427,11 @@ _Related_ _Parameters_ - _content_ `string`: The post content. -- _options_ `ParseOptions`: Extra options for handling block parsing. +- _options_ `BlockParseOptions`: Extra options for handling block parsing. _Returns_ -- `Array`: Block list. +- `Block[]`: Block list. ### parseWithAttributeSchema @@ -440,11 +440,11 @@ Given a block's raw content and an attribute's schema returns the attribute's va _Parameters_ - _innerHTML_ `string|Node`: Block's raw content. -- _attributeSchema_ `Object`: Attribute's schema. +- _attributeSchema_ `AttributeSchema`: Attribute's schema. _Returns_ -- `*`: Attribute value. +- `import('../../types').SourceReturnValue`: Attribute value. ### pasteHandler @@ -501,9 +501,7 @@ registerBlockType( 'my-collection/block-name', { _Parameters_ - _namespace_ `string`: The namespace to group blocks by in the inserter; corresponds to the block namespace. -- _settings_ `Object`: The block collection settings. -- _settings.title_ `string`: The title to display in the block inserter. -- _settings.icon_ `[Object]`: The icon to display in the block inserter. +- _settings_ `BlockCollection`: The block collection settings. ### registerBlockStyle @@ -537,7 +535,7 @@ const ExampleComponent = () => { _Parameters_ - _blockName_ `string`: Name of block (example: “core/latest-posts”). -- _styleVariation_ `Object`: Object containing `name` which is the class name applied to the block and `label` which identifies the variation to the user. +- _styleVariation_ `BlockStyle`: Object containing `name` which is the class name applied to the block and `label` which identifies the variation to the user. ### registerBlockType @@ -560,12 +558,12 @@ registerBlockType( 'namespace/block-name', { _Parameters_ -- _blockNameOrMetadata_ `string|Object`: Block type name or its metadata. -- _settings_ `Object`: Block settings. +- _blockNameOrMetadata_ `string|BlockMetadata`: Block type name or its metadata. +- _settings_ `(Partial|BlockMetadata)=`: Block settings. _Returns_ -- `WPBlockType | undefined`: The block, if it has been successfully registered; otherwise `undefined`. +- `BlockType|undefined`: The block, if it has been successfully registered; otherwise `undefined`. ### registerBlockVariation @@ -600,7 +598,7 @@ const ExampleComponent = () => { _Parameters_ - _blockName_ `string`: Name of the block (example: “core/columns”). -- _variation_ `WPBlockVariation`: Object describing a block variation. +- _variation_ `BlockVariation`: Object describing a block variation. ### serialize @@ -608,8 +606,8 @@ Takes a block or set of blocks and returns the serialized post content. _Parameters_ -- _blocks_ `Array`: Block(s) to serialize. -- _options_ `WPBlockSerializationOptions`: Serialization options. +- _blocks_ `Block[]`: Block(s) to serialize. +- _options_ `BlockSerializationOptions=`: Serialization options. _Returns_ @@ -622,14 +620,14 @@ Serializes a block node into the native HTML-comment-powered block format. CAVEA _Related_ - serializeBlock -- serialize For more on the format of block nodes as returned by valid parsers: -- `@wordpress/block-serialization-default-parser` package -- `@wordpress/block-serialization-spec-parser` package +- serialize +- +- _Parameters_ -- _rawBlock_ `WPRawBlock`: A block node as returned by a valid parser. -- _options_ `[Options]`: Serialization options. +- _rawBlock_ `BlockNode`: A block node as returned by a valid parser. +- _options_ `BlockSerializationOptions=`: Serialization options. _Returns_ @@ -672,7 +670,7 @@ const ExampleComponent = () => { _Parameters_ -- _categories_ `WPBlockCategory[]`: Block categories. +- _categories_ `BlockCategory[]`: Block categories. ### setDefaultBlockName @@ -754,12 +752,12 @@ Switch one or more blocks into one or more blocks of the new block type. _Parameters_ -- _blocks_ `Array|Object`: Blocks array or block object. +- _blocks_ `Block[]|Block`: Blocks array or block object. - _name_ `string`: Block name. _Returns_ -- `?Array`: Array of blocks or null. +- `Block[]|null`: Array of blocks or null. ### synchronizeBlocksWithTemplate @@ -769,12 +767,12 @@ Synchronizing a block list with a block template means that we loop over the blo _Parameters_ -- _blocks_ `Array`: Block list. -- _template_ `Array`: Block template. +- _blocks_ `Block[]`: Block list. +- _template_ `InnerBlockTemplate[]=`: Block template. _Returns_ -- `Array`: Updated Block list. +- `Block[]`: Updated Block list. ### unregisterBlockStyle @@ -832,7 +830,7 @@ _Parameters_ _Returns_ -- `WPBlockType | undefined`: The previous block value, if it has been successfully unregistered; otherwise `undefined`. +- `BlockType|undefined`: The previous block value, if it has been successfully unregistered; otherwise `undefined`. ### unregisterBlockVariation @@ -890,7 +888,7 @@ const ExampleComponent = () => { _Parameters_ - _slug_ `string`: Block category slug. -- _category_ `WPBlockCategory`: Object containing the category properties that should be updated. +- _category_ `BlockCategory`: Object containing the category properties that should be updated. ### validateBlock @@ -898,8 +896,8 @@ Returns an object with `isValid` property set to `true` if the parsed block is v _Parameters_ -- _block_ `WPBlock`: block object. -- _blockTypeOrName_ `[WPBlockType|string]`: Block type or name, inferred from block if not given. +- _block_ `Block`: block object. +- _blockTypeOrName_ `(BlockType|string)=`: Block type or name, inferred from block if not given. _Returns_ @@ -919,6 +917,10 @@ _Returns_ - `Component`: The same component. +_Type Definition_ + +- _Component_ `import('react').ComponentType` + ## Contributing to this package diff --git a/packages/blocks/package.json b/packages/blocks/package.json index ab13a27bc3789..dac2e4786adc1 100644 --- a/packages/blocks/package.json +++ b/packages/blocks/package.json @@ -24,6 +24,7 @@ "main": "build/index.js", "module": "build-module/index.js", "react-native": "src/index", + "types": "build-types", "sideEffects": [ "{src,build,build-module}/{index.js,store/index.js}" ], diff --git a/packages/blocks/src/api/categories.js b/packages/blocks/src/api/categories.js index f73331066fed9..86a2c50a0a588 100644 --- a/packages/blocks/src/api/categories.js +++ b/packages/blocks/src/api/categories.js @@ -8,7 +8,9 @@ import { dispatch, select } from '@wordpress/data'; */ import { store as blocksStore } from '../store'; -/** @typedef {import('../store/reducer').WPBlockCategory} WPBlockCategory */ +/** + * @typedef {import('../types').BlockCategory} BlockCategory + */ /** * Returns all the block categories. @@ -16,7 +18,7 @@ import { store as blocksStore } from '../store'; * * @ignore * - * @return {WPBlockCategory[]} Block categories. + * @return {BlockCategory[]} Block categories. */ export function getCategories() { return select( blocksStore ).getCategories(); @@ -25,7 +27,7 @@ export function getCategories() { /** * Sets the block categories. * - * @param {WPBlockCategory[]} categories Block categories. + * @param {BlockCategory[]} categories Block categories. * * @example * ```js @@ -64,9 +66,9 @@ export function setCategories( categories ) { /** * Updates a category. * - * @param {string} slug Block category slug. - * @param {WPBlockCategory} category Object containing the category properties - * that should be updated. + * @param {string} slug Block category slug. + * @param {BlockCategory} category Object containing the category properties + * that should be updated. * * @example * ```js diff --git a/packages/blocks/src/api/children.js b/packages/blocks/src/api/children.js index fe46a30870af9..20ea7554b74db 100644 --- a/packages/blocks/src/api/children.js +++ b/packages/blocks/src/api/children.js @@ -10,17 +10,15 @@ import deprecated from '@wordpress/deprecated'; import * as node from './node'; /** - * A representation of a block's rich text value. - * - * @typedef {WPBlockNode[]} WPBlockChildren + * @typedef {import('react').ReactChild} ReactChild */ /** * Given block children, returns a serialize-capable WordPress element. * - * @param {WPBlockChildren} children Block children object to convert. + * @param {ReactChild[]} children Block children object to convert. * - * @return {Element} A serialize-capable element. + * @return {ReactChild[]} A serialize-capable element. */ export function getSerializeCapableElement( children ) { // The fact that block children are compatible with the element serializer is @@ -35,9 +33,11 @@ export function getSerializeCapableElement( children ) { /** * Given block children, returns an array of block nodes. * - * @param {WPBlockChildren} children Block children object to convert. + * @param {ReactChild[]} children Block children object to convert. + * + * @return {ReactChild[]} An array of individual block nodes. * - * @return {Array} An array of individual block nodes. + * @deprecated since 11.17.0. Use the html source instead. */ function getChildrenArray( children ) { deprecated( 'wp.blocks.children.getChildrenArray', { @@ -56,9 +56,11 @@ function getChildrenArray( children ) { * Given two or more block nodes, returns a new block node representing a * concatenation of its values. * - * @param {...WPBlockChildren} blockNodes Block nodes to concatenate. + * @param {...ReactChild[]} blockNodes Block nodes to concatenate. + * + * @return {ReactChild[]} Concatenated block node. * - * @return {WPBlockChildren} Concatenated block node. + * @deprecated since 11.17.0. Use the html source instead. */ export function concat( ...blockNodes ) { deprecated( 'wp.blocks.children.concat', { @@ -94,9 +96,11 @@ export function concat( ...blockNodes ) { * Given an iterable set of DOM nodes, returns equivalent block children. * Ignores any non-element/text nodes included in set. * - * @param {Iterable.} domNodes Iterable set of DOM nodes to convert. + * @param {ArrayLike} domNodes Iterable set of DOM nodes to convert. * - * @return {WPBlockChildren} Block children equivalent to DOM nodes. + * @return {ReactChild[]} Block children equivalent to DOM nodes. + * + * @deprecated since 11.17.0. Use the html source instead. */ export function fromDOM( domNodes ) { deprecated( 'wp.blocks.children.fromDOM', { @@ -121,9 +125,11 @@ export function fromDOM( domNodes ) { /** * Given a block node, returns its HTML string representation. * - * @param {WPBlockChildren} children Block node(s) to convert to string. + * @param {ReactChild[]} children Block node(s) to convert to string. * * @return {string} String HTML representation of block node. + * + * @deprecated since 11.17.0. Use the html source instead. */ export function toHTML( children ) { deprecated( 'wp.blocks.children.toHTML', { @@ -139,12 +145,14 @@ export function toHTML( children ) { } /** - * Given a selector, returns an hpq matcher generating a WPBlockChildren value + * Given a selector, returns an hpq matcher generating a BlockChildren value * matching the selector result. * - * @param {string} selector DOM selector. + * @param {string=} selector DOM selector. + * + * @return {(domNode: Node & ParentNode) => ReactChild[]} hpq matcher. * - * @return {Function} hpq matcher. + * @deprecated since 11.17.0. Use the html source instead. */ export function matcher( selector ) { deprecated( 'wp.blocks.children.matcher', { @@ -155,6 +163,7 @@ export function matcher( selector ) { } ); return ( domNode ) => { + /** @type {(Node & ParentNode)|null} */ let match = domNode; if ( selector ) { diff --git a/packages/blocks/src/api/factory.js b/packages/blocks/src/api/factory.js index 53333ef688085..3a14e28befd02 100644 --- a/packages/blocks/src/api/factory.js +++ b/packages/blocks/src/api/factory.js @@ -21,14 +21,22 @@ import { __experimentalSanitizeBlockAttributes, } from './utils'; +/** + * @typedef {import('../types').Block} Block + * @typedef {import('../types').BlockType} BlockType + * @typedef {import('../types').BlockAttributes} BlockAttributes + * @typedef {import('../types').InnerBlockTemplate} InnerBlockTemplate + * @typedef {import('../types').Transform} Transform + */ + /** * Returns a block object given its type and attributes. * - * @param {string} name Block name. - * @param {Object} attributes Block attributes. - * @param {?Array} innerBlocks Nested blocks. + * @param {string} name Block name. + * @param {BlockAttributes} attributes Block attributes. + * @param {Block[]=} innerBlocks Nested blocks. * - * @return {Object} Block object. + * @return {Block} Block object. */ export function createBlock( name, attributes = {}, innerBlocks = [] ) { const sanitizedAttributes = __experimentalSanitizeBlockAttributes( @@ -55,9 +63,9 @@ export function createBlock( name, attributes = {}, innerBlocks = [] ) { * It handles the case of having InnerBlocks as Blocks by * converting them to the proper format to continue recursively. * - * @param {Array} innerBlocksOrTemplate Nested blocks or InnerBlocks templates. + * @param {Array} innerBlocksOrTemplate Nested blocks or InnerBlocks templates. * - * @return {Object[]} Array of Block objects. + * @return {Block[]} Array of Block objects. */ export function createBlocksFromInnerBlocksTemplate( innerBlocksOrTemplate = [] @@ -83,11 +91,11 @@ export function createBlocksFromInnerBlocksTemplate( * Given a block object, returns a copy of the block object while sanitizing its attributes, * optionally merging new attributes and/or replacing its inner blocks. * - * @param {Object} block Block instance. - * @param {Object} mergeAttributes Block attributes. - * @param {?Array} newInnerBlocks Nested blocks. + * @param {Block} block Block instance. + * @param {BlockAttributes} mergeAttributes Block attributes. + * @param {Block[]=} newInnerBlocks Nested blocks. * - * @return {Object} A cloned block. + * @return {Block} A cloned block. */ export function __experimentalCloneSanitizedBlock( block, @@ -120,9 +128,9 @@ export function __experimentalCloneSanitizedBlock( * Given a block object, returns a copy of the block object, * optionally merging new attributes and/or replacing its inner blocks. * - * @param {Object} block Block instance. - * @param {Object} mergeAttributes Block attributes. - * @param {?Array} newInnerBlocks Nested blocks. + * @param {Block} block Block instance. + * @param {BlockAttributes} mergeAttributes Block attributes. + * @param {Block[]=} newInnerBlocks Nested blocks. * * @return {Object} A cloned block. */ @@ -146,9 +154,9 @@ export function cloneBlock( block, mergeAttributes = {}, newInnerBlocks ) { * Returns a boolean indicating whether a transform is possible based on * various bits of context. * - * @param {Object} transform The transform object to validate. - * @param {string} direction Is this a 'from' or 'to' transform. - * @param {Array} blocks The blocks to transform from. + * @param {Transform} transform The transform object to validate. + * @param {'from'|'to'} direction Is this a 'from' or 'to' transform. + * @param {Block[]} blocks The blocks to transform from. * * @return {boolean} Is the transform possible? */ @@ -218,9 +226,9 @@ const isPossibleTransformForSource = ( transform, direction, blocks ) => { * Returns block types that the 'blocks' can be transformed into, based on * 'from' transforms on other blocks. * - * @param {Array} blocks The blocks to transform from. + * @param {Block[]} blocks The blocks to transform from. * - * @return {Array} Block types that the blocks can be transformed into. + * @return {BlockType[]} Block types that the blocks can be transformed into. */ const getBlockTypesForPossibleFromTransforms = ( blocks ) => { if ( ! blocks.length ) { @@ -250,9 +258,9 @@ const getBlockTypesForPossibleFromTransforms = ( blocks ) => { * Returns block types that the 'blocks' can be transformed into, based on * the source block's own 'to' transforms. * - * @param {Array} blocks The blocks to transform from. + * @param {Block[]} blocks The blocks to transform from. * - * @return {Array} Block types that the source can be transformed into. + * @return {BlockType[]} Block types that the source can be transformed into. */ const getBlockTypesForPossibleToTransforms = ( blocks ) => { if ( ! blocks.length ) { @@ -286,7 +294,7 @@ const getBlockTypesForPossibleToTransforms = ( blocks ) => { * and if so whether it is a "wildcard" transform * ie: targets "any" block type * - * @param {Object} t the Block transform object + * @param {Transform} t the Block transform object * * @return {boolean} whether transform is a wildcard transform */ @@ -312,9 +320,9 @@ export const isContainerGroupBlock = ( name ) => * Returns an array of block types that the set of blocks received as argument * can be transformed into. * - * @param {Array} blocks Blocks array. + * @param {Block[]} blocks Blocks array. * - * @return {Array} Block types that the blocks argument can be transformed to. + * @return {BlockType[]} Block types that the blocks argument can be transformed to. */ export function getPossibleBlockTransformations( blocks ) { if ( ! blocks.length ) { @@ -341,10 +349,10 @@ export function getPossibleBlockTransformations( blocks ) { * null if the transforms set is empty or the predicate function returns a * falsey value for all entries. * - * @param {Object[]} transforms Transforms to search. - * @param {Function} predicate Function returning true on matching transform. + * @param {Transform[]} transforms Transforms to search. + * @param {(transform: Transform) => boolean} predicate Function returning true on matching transform. * - * @return {?Object} Highest-priority transform candidate. + * @return {Transform|undefined} Highest-priority transform candidate. */ export function findTransform( transforms, predicate ) { // The hooks library already has built-in mechanisms for managing priority @@ -373,10 +381,10 @@ export function findTransform( transforms, predicate ) { * If no block name is provided, returns transforms for all blocks. A normal * transform object includes `blockName` as a property. * - * @param {string} direction Transform direction ("to", "from"). - * @param {string|Object} blockTypeOrName Block type or name. + * @param {'from'|'to'} direction Transform direction ("to", "from"). + * @param {BlockType|string} blockTypeOrName Block type or name. * - * @return {Array} Block transforms for direction. + * @return {Transform[]} Block transforms for direction. */ export function getBlockTransforms( direction, blockTypeOrName ) { // When retrieving transforms for all block types, recurse into self. @@ -429,8 +437,8 @@ export function getBlockTransforms( direction, blockTypeOrName ) { /** * Checks that a given transforms isMatch method passes for given source blocks. * - * @param {Object} transform A transform object. - * @param {Array} blocks Blocks array. + * @param {Transform} transform A transform object. + * @param {Block[]} blocks Blocks array. * * @return {boolean} True if given blocks are a match for the transform. */ @@ -450,10 +458,10 @@ function maybeCheckTransformIsMatch( transform, blocks ) { /** * Switch one or more blocks into one or more blocks of the new block type. * - * @param {Array|Object} blocks Blocks array or block object. - * @param {string} name Block name. + * @param {Block[]|Block} blocks Blocks array or block object. + * @param {string} name Block name. * - * @return {?Array} Array of blocks or null. + * @return {Block[]|null} Array of blocks or null. */ export function switchToBlockType( blocks, name ) { const blocksArray = Array.isArray( blocks ) ? blocks : [ blocks ]; @@ -491,6 +499,7 @@ export function switchToBlockType( blocks, name ) { return null; } + /** @type {Block|Block[]|null} */ let transformationResults; if ( transformation.isMultiBlock ) { @@ -554,10 +563,10 @@ export function switchToBlockType( blocks, name ) { * All of the original blocks are passed, since transformations are * many-to-many, not one-to-one. * - * @param {Object} transformedBlock The transformed block. - * @param {Object[]} blocks Original blocks transformed. + * @param {Block} transformedBlock The transformed block. + * @param {Block[]} blocks Original blocks transformed. * @param {Object[]} index Index of the transformed block on the array of results. - * @param {Object[]} results An array all the blocks that resulted from the transformation. + * @param {Block[]} results An array all the blocks that resulted from the transformation. */ return applyFilters( 'blocks.switchToBlockType.transformedBlock', @@ -575,9 +584,9 @@ export function switchToBlockType( blocks, name ) { * Create a block object from the example API. * * @param {string} name - * @param {Object} example + * @param {Block} example * - * @return {Object} block. + * @return {Block} block. */ export const getBlockFromExample = ( name, example ) => { try { diff --git a/packages/blocks/src/api/matchers.js b/packages/blocks/src/api/matchers.js index 950f1539440a0..9c38ace3a28f6 100644 --- a/packages/blocks/src/api/matchers.js +++ b/packages/blocks/src/api/matchers.js @@ -14,6 +14,13 @@ import { RichTextData } from '@wordpress/rich-text'; export { matcher as node } from './node'; export { matcher as children } from './children'; +/** + * Higher order HTML selector matching function. + * + * @param {string=} selector Selector to use for matching. + * @param {string=} multilineTag Child node tag name to select from match. + * @return {(domNode: Node) => string|undefined} The matching function. + */ export function html( selector, multilineTag ) { return ( domNode ) => { let match = domNode; diff --git a/packages/blocks/src/api/node.js b/packages/blocks/src/api/node.js index 5db58647c3988..e39f18206376e 100644 --- a/packages/blocks/src/api/node.js +++ b/packages/blocks/src/api/node.js @@ -9,24 +9,20 @@ import deprecated from '@wordpress/deprecated'; import * as children from './children'; /** - * A representation of a single node within a block's rich text value. If - * representing a text node, the value is simply a string of the node value. - * As representing an element node, it is an object of: - * - * 1. `type` (string): Tag name. - * 2. `props` (object): Attributes and children array of WPBlockNode. - * - * @typedef {string|Object} WPBlockNode + * @typedef {import('react').ReactChild} ReactChild + * @typedef {import('react').ReactElement} Element */ /** * Given a single node and a node type (e.g. `'br'`), returns true if the node * corresponds to that type, false otherwise. * - * @param {WPBlockNode} node Block node to test - * @param {string} type Node to type to test against. + * @param {Element} node Block node to test + * @param {Element['type']} type Node to type to test against. * * @return {boolean} Whether node is of intended type. + * + * @deprecated since 11.17.0. Use the html source instead. */ function isNodeOfType( node, type ) { deprecated( 'wp.blocks.node.isNodeOfType', { @@ -66,7 +62,9 @@ export function getNamedNodeMapAsObject( nodeMap ) { * * @param {Node} domNode DOM node to convert. * - * @return {WPBlockNode} Block node equivalent to DOM node. + * @return {Element} Block node equivalent to DOM node. + * + * @deprecated since 11.17.0. Use the html source instead. */ export function fromDOM( domNode ) { deprecated( 'wp.blocks.node.fromDOM', { @@ -99,9 +97,11 @@ export function fromDOM( domNode ) { /** * Given a block node, returns its HTML string representation. * - * @param {WPBlockNode} node Block node to convert to string. + * @param {ReactChild} node Block node to convert to string. * * @return {string} String HTML representation of block node. + * + * @deprecated since 11.17.0. Use the html source instead. */ export function toHTML( node ) { deprecated( 'wp.blocks.node.toHTML', { @@ -115,12 +115,14 @@ export function toHTML( node ) { } /** - * Given a selector, returns an hpq matcher generating a WPBlockNode value + * Given a selector, returns an hpq matcher generating a BlockNode value * matching the selector result. * - * @param {string} selector DOM selector. + * @param {string=} selector DOM selector. + * + * @return {(domNode: Node & ParentNode) => ReactChild[]} hpq matcher. * - * @return {Function} hpq matcher. + * @deprecated since 11.17.0. Use the html source instead. */ export function matcher( selector ) { deprecated( 'wp.blocks.node.matcher', { diff --git a/packages/blocks/src/api/parser/apply-block-deprecated-versions.js b/packages/blocks/src/api/parser/apply-block-deprecated-versions.js index 6c9d81d47b031..595955dbb4daa 100644 --- a/packages/blocks/src/api/parser/apply-block-deprecated-versions.js +++ b/packages/blocks/src/api/parser/apply-block-deprecated-versions.js @@ -7,6 +7,12 @@ import { getBlockAttributes } from './get-block-attributes'; import { applyBuiltInValidationFixes } from './apply-built-in-validation-fixes'; import { omit } from '../utils'; +/** + * @typedef {import('../../types').Block} Block + * @typedef {import('../../types').BlockType} BlockType + * @typedef {import('../../types').BlockNode} BlockNode + */ + /** * Function that takes no arguments and always returns false. * @@ -21,13 +27,13 @@ function stubFalse() { * deprecated migrations applied, or the original block if it was both valid * and no eligible migrations exist. * - * @param {import(".").WPBlock} block Parsed and invalid block object. - * @param {import(".").WPRawBlock} rawBlock Raw block object. - * @param {import('../registration').WPBlockType} blockType Block type. This is normalize not necessary and - * can be inferred from the block name, - * but it's here for performance reasons. + * @param {Block} block Parsed and invalid block object. + * @param {BlockNode} rawBlock Raw block object. + * @param {BlockType} blockType Block type. This is normalize not necessary and + * can be inferred from the block name, + * but it's here for performance reasons. * - * @return {import(".").WPBlock} Migrated block object. + * @return {Block} Migrated block object. */ export function applyBlockDeprecatedVersions( block, rawBlock, blockType ) { const parsedAttributes = rawBlock.attrs; diff --git a/packages/blocks/src/api/parser/apply-built-in-validation-fixes.js b/packages/blocks/src/api/parser/apply-built-in-validation-fixes.js index 13dbb1e6825c9..189ad8183f1fa 100644 --- a/packages/blocks/src/api/parser/apply-built-in-validation-fixes.js +++ b/packages/blocks/src/api/parser/apply-built-in-validation-fixes.js @@ -3,16 +3,21 @@ */ import { fixCustomClassname } from './fix-custom-classname'; +/** + * @typedef {import('../../types').Block} Block + * @typedef {import('../../types').BlockType} BlockType + */ + /** * Attempts to fix block invalidation by applying build-in validation fixes * like moving all extra classNames to the className attribute. * - * @param {WPBlock} block block object. - * @param {import('../registration').WPBlockType} blockType Block type. This is normalize not necessary and - * can be inferred from the block name, - * but it's here for performance reasons. + * @param {Block} block block object. + * @param {BlockType} blockType Block type. This is normalize not necessary and + * can be inferred from the block name, + * but it's here for performance reasons. * - * @return {WPBlock} Fixed block object + * @return {Block} Fixed block object */ export function applyBuiltInValidationFixes( block, blockType ) { const updatedBlockAttributes = fixCustomClassname( diff --git a/packages/blocks/src/api/parser/convert-legacy-block.js b/packages/blocks/src/api/parser/convert-legacy-block.js index c828a3f5db6c4..d20a593921d51 100644 --- a/packages/blocks/src/api/parser/convert-legacy-block.js +++ b/packages/blocks/src/api/parser/convert-legacy-block.js @@ -1,12 +1,16 @@ +/** + * @typedef {import('../../types').BlockAttributes} BlockAttributes + */ + /** * Convert legacy blocks to their canonical form. This function is used * both in the parser level for previous content and to convert such blocks * used in Custom Post Types templates. * - * @param {string} name The block's name - * @param {Object} attributes The block's attributes + * @param {string} name The block's name + * @param {BlockAttributes} attributes The block's attributes * - * @return {[string, Object]} The block's name and attributes, changed accordingly if a match was found + * @return {[string, BlockAttributes]} The block's name and attributes, changed accordingly if a match was found */ export function convertLegacyBlockNameAndAttributes( name, attributes ) { const newAttributes = { ...attributes }; diff --git a/packages/blocks/src/api/parser/fix-custom-classname.js b/packages/blocks/src/api/parser/fix-custom-classname.js index d72065cd59222..eb1aa262e23f0 100644 --- a/packages/blocks/src/api/parser/fix-custom-classname.js +++ b/packages/blocks/src/api/parser/fix-custom-classname.js @@ -5,6 +5,11 @@ import { hasBlockSupport } from '../registration'; import { getSaveContent } from '../serializer'; import { parseWithAttributeSchema } from './get-block-attributes'; +/** + * @typedef {import('../../types').BlockType} BlockType + * @typedef {import('../../types').BlockAttributes} BlockAttributes + */ + const CLASS_ATTR_SCHEMA = { type: 'string', source: 'attribute', @@ -35,11 +40,11 @@ export function getHTMLRootElementClasses( innerHTML ) { * found, the unknown classes are treated as custom classes. This prevents the * block from being considered as invalid. * - * @param {Object} blockAttributes Original block attributes. - * @param {Object} blockType Block type settings. - * @param {string} innerHTML Original block markup. + * @param {BlockAttributes} blockAttributes Original block attributes. + * @param {BlockType} blockType Block type settings. + * @param {string} innerHTML Original block markup. * - * @return {Object} Filtered block attributes. + * @return {BlockAttributes} Filtered block attributes. */ export function fixCustomClassname( blockAttributes, blockType, innerHTML ) { if ( hasBlockSupport( blockType, 'customClassName', true ) ) { diff --git a/packages/blocks/src/api/parser/get-block-attributes.js b/packages/blocks/src/api/parser/get-block-attributes.js index 24faae7370463..308922cbefdfd 100644 --- a/packages/blocks/src/api/parser/get-block-attributes.js +++ b/packages/blocks/src/api/parser/get-block-attributes.js @@ -26,6 +26,13 @@ import { } from '../matchers'; import { normalizeBlockType, getDefault } from '../utils'; +/** + * @typedef {import('../../types').BlockType} BlockType + * @typedef {import('../../types').BlockAttributes} BlockAttributes + * @typedef {import('../../types').BlockAttributeSchema} BlockAttributeSchema + * @typedef {import('../../types').AttributeSchemaType} AttributeSchemaType + */ + /** * Higher-order hpq matcher which enhances an attribute matcher to return true * or false depending on whether the original matcher returns undefined. This @@ -61,8 +68,8 @@ export const toBooleanAttributeMatcher = ( matcher ) => * * @see http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.25 * - * @param {*} value Value to test. - * @param {string} type Type to test. + * @param {*} value Value to test. + * @param {AttributeSchemaType} type Type to test. * * @return {boolean} Whether value is of type. */ @@ -100,8 +107,8 @@ export function isOfType( value, type ) { * * @see http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.25 * - * @param {*} value Value to test. - * @param {string[]} types Types to test. + * @param {*} value Value to test. + * @param {AttributeSchemaType[]} types Types to test. * * @return {boolean} Whether value is of types. */ @@ -114,11 +121,11 @@ export function isOfTypes( value, types ) { * commentAttributes returns the attribute value depending on its source * definition of the given attribute key. * - * @param {string} attributeKey Attribute key. - * @param {Object} attributeSchema Attribute's schema. - * @param {Node} innerDOM Parsed DOM of block's inner HTML. - * @param {Object} commentAttributes Block's comment attributes. - * @param {string} innerHTML Raw HTML from block node's innerHTML property. + * @param {string} attributeKey Attribute key. + * @param {BlockAttributeSchema} attributeSchema Attribute's schema. + * @param {Node} innerDOM Parsed DOM of block's inner HTML. + * @param {Record} commentAttributes Block's comment attributes. + * @param {string} innerHTML Raw HTML from block node's innerHTML property. * * @return {*} Attribute value. */ @@ -178,8 +185,8 @@ export function getBlockAttribute( * * @see https://json-schema.org/latest/json-schema-validation.html#rfc.section.6.1.1 * - * @param {*} value Value to test. - * @param {?(Array|string)} type Block attribute schema type. + * @param {*} value Value to test. + * @param {(AttributeSchemaType|AttributeSchemaType[])=} type Block attribute schema type. * * @return {boolean} Whether value is valid. */ @@ -196,8 +203,8 @@ export function isValidByType( value, type ) { * * @see https://json-schema.org/latest/json-schema-validation.html#rfc.section.6.1.2 * - * @param {*} value Value to test. - * @param {?Array} enumSet Block attribute schema enum. + * @param {*} value Value to test. + * @param {string[]=} enumSet Block attribute schema enum. * * @return {boolean} Whether value is valid. */ @@ -208,7 +215,7 @@ export function isValidByEnum( value, enumSet ) { /** * Returns an hpq matcher given a source object. * - * @param {Object} sourceConfig Attribute Source object. + * @param {BlockAttributeSchema} sourceConfig Attribute Source object. * * @return {Function} A hpq Matcher. */ @@ -271,10 +278,12 @@ function parseHtml( innerHTML ) { * Given a block's raw content and an attribute's schema returns the attribute's * value depending on its source. * - * @param {string|Node} innerHTML Block's raw content. - * @param {Object} attributeSchema Attribute's schema. + * @template {BlockAttributeSchema} AttributeSchema * - * @return {*} Attribute value. + * @param {string|Node} innerHTML Block's raw content. + * @param {AttributeSchema} attributeSchema Attribute's schema. + * + * @return {import('../../types').SourceReturnValue} Attribute value. */ export function parseWithAttributeSchema( innerHTML, attributeSchema ) { return matcherFromSource( attributeSchema )( parseHtml( innerHTML ) ); @@ -283,11 +292,13 @@ export function parseWithAttributeSchema( innerHTML, attributeSchema ) { /** * Returns the block attributes of a registered block node given its type. * - * @param {string|Object} blockTypeOrName Block type or name. - * @param {string|Node} innerHTML Raw block content. - * @param {?Object} attributes Known block attributes (from delimiters). + * @template {BlockType} T + * + * @param {T|string} blockTypeOrName Block type or name. + * @param {string|Node} innerHTML Raw block content. + * @param {Partial=} attributes Known block attributes (from delimiters). * - * @return {Object} All block attributes. + * @return {T extends import('../../types').BlockType> ? U : Record} All block attributes. */ export function getBlockAttributes( blockTypeOrName, diff --git a/packages/blocks/src/api/parser/index.js b/packages/blocks/src/api/parser/index.js index f8ff0c68964dc..860613eff1620 100644 --- a/packages/blocks/src/api/parser/index.js +++ b/packages/blocks/src/api/parser/index.js @@ -22,38 +22,10 @@ import { applyBlockDeprecatedVersions } from './apply-block-deprecated-versions' import { applyBuiltInValidationFixes } from './apply-built-in-validation-fixes'; /** - * The raw structure of a block includes its attributes, inner - * blocks, and inner HTML. It is important to distinguish inner blocks from - * the HTML content of the block as only the latter is relevant for block - * validation and edit operations. - * - * @typedef WPRawBlock - * - * @property {string=} blockName Block name - * @property {Object=} attrs Block raw or comment attributes. - * @property {string} innerHTML HTML content of the block. - * @property {(string|null)[]} innerContent Content without inner blocks. - * @property {WPRawBlock[]} innerBlocks Inner Blocks. - */ - -/** - * Fully parsed block object. - * - * @typedef WPBlock - * - * @property {string} name Block name - * @property {Object} attributes Block raw or comment attributes. - * @property {WPBlock[]} innerBlocks Inner Blocks. - * @property {string} originalContent Original content of the block before validation fixes. - * @property {boolean} isValid Whether the block is valid. - * @property {Object[]} validationIssues Validation issues. - * @property {WPRawBlock} [__unstableBlockSource] Un-processed original copy of block if created through parser. - */ - -/** - * @typedef {Object} ParseOptions - * @property {boolean?} __unstableSkipMigrationLogs If a block is migrated from a deprecated version, skip logging the migration details. - * @property {boolean?} __unstableSkipAutop Whether to skip autop when processing freeform content. + * @typedef {import('../../types').Block} Block + * @typedef {import('../../types').BlockType} BlockType + * @typedef {import('../../types').BlockNode} BlockNode + * @typedef {import('../types').BlockParseOptions} BlockParseOptions */ /** @@ -61,9 +33,9 @@ import { applyBuiltInValidationFixes } from './apply-built-in-validation-fixes'; * both in the parser level for previous content and to convert such blocks * used in Custom Post Types templates. * - * @param {WPRawBlock} rawBlock + * @param {BlockNode} rawBlock * - * @return {WPRawBlock} The block's name and attributes, changed accordingly if a match was found + * @return {BlockNode} The block's name and attributes, changed accordingly if a match was found */ function convertLegacyBlocks( rawBlock ) { const [ correctName, correctedAttributes ] = @@ -82,10 +54,10 @@ function convertLegacyBlocks( rawBlock ) { * Normalize the raw block by applying the fallback block name if none given, * sanitize the parsed HTML... * - * @param {WPRawBlock} rawBlock The raw block object. - * @param {ParseOptions?} options Extra options for handling block parsing. + * @param {BlockNode} rawBlock The raw block object. + * @param {BlockParseOptions=} options Extra options for handling block parsing. * - * @return {WPRawBlock} The normalized block object. + * @return {BlockNode} The normalized block object. */ export function normalizeRawBlock( rawBlock, options ) { const fallbackBlockName = getFreeformContentHandlerName(); @@ -119,9 +91,9 @@ export function normalizeRawBlock( rawBlock, options ) { /** * Uses the "unregistered blockType" to create a block object. * - * @param {WPRawBlock} rawBlock block. + * @param {BlockNode} rawBlock block. * - * @return {WPRawBlock} The unregistered block object. + * @return {BlockNode} The unregistered block object. */ function createMissingBlockType( rawBlock ) { const unregisteredFallbackBlock = @@ -158,9 +130,9 @@ function createMissingBlockType( rawBlock ) { * * The name here is regrettable but `validateBlock` is already taken. * - * @param {WPBlock} unvalidatedBlock - * @param {import('../registration').WPBlockType} blockType - * @return {WPBlock} validated block, with auto-fixes if initially invalid + * @param {Block} unvalidatedBlock + * @param {BlockType} blockType + * @return {Block} validated block, with auto-fixes if initially invalid */ function applyBlockValidation( unvalidatedBlock, blockType ) { // Attempt to validate the block. @@ -188,10 +160,10 @@ function applyBlockValidation( unvalidatedBlock, blockType ) { /** * Given a raw block returned by grammar parsing, returns a fully parsed block. * - * @param {WPRawBlock} rawBlock The raw block object. - * @param {ParseOptions} options Extra options for handling block parsing. + * @param {BlockNode} rawBlock The raw block object. + * @param {BlockParseOptions} options Extra options for handling block parsing. * - * @return {WPBlock | undefined} Fully parsed block. + * @return {Block|undefined} Fully parsed block. */ export function parseRawBlock( rawBlock, options ) { let normalizedBlock = normalizeRawBlock( rawBlock, options ); @@ -302,10 +274,10 @@ export function parseRawBlock( rawBlock, options ) { * @see * https://developer.wordpress.org/block-editor/packages/packages-block-serialization-default-parser/ * - * @param {string} content The post content. - * @param {ParseOptions} options Extra options for handling block parsing. + * @param {string} content The post content. + * @param {BlockParseOptions} options Extra options for handling block parsing. * - * @return {Array} Block list. + * @return {Block[]} Block list. */ export default function parse( content, options ) { return grammarParse( content ).reduce( ( accumulator, rawBlock ) => { diff --git a/packages/blocks/src/api/parser/serialize-raw-block.js b/packages/blocks/src/api/parser/serialize-raw-block.js index f84cedb786413..e73d8a6698537 100644 --- a/packages/blocks/src/api/parser/serialize-raw-block.js +++ b/packages/blocks/src/api/parser/serialize-raw-block.js @@ -4,12 +4,12 @@ import { getCommentDelimitedContent } from '../serializer'; /** - * @typedef {Object} Options Serialization options. - * @property {boolean} [isCommentDelimited=true] Whether to output HTML comments around blocks. + * @typedef {import('../../types').BlockNode} BlockNode + * @typedef {import('../serializer')} serialize + * @typedef {import('../serializer').serializeBlock} serializeBlock + * @typedef {import('../types').BlockSerializationOptions} BlockSerializationOptions */ -/** @typedef {import("./").WPRawBlock} WPRawBlock */ - /** * Serializes a block node into the native HTML-comment-powered block format. * CAVEAT: This function is intended for re-serializing blocks as parsed by @@ -20,13 +20,11 @@ import { getCommentDelimitedContent } from '../serializer'; * @see serializeBlock * @see serialize * - * For more on the format of block nodes as returned by valid parsers: - * - * @see `@wordpress/block-serialization-default-parser` package - * @see `@wordpress/block-serialization-spec-parser` package + * @see {@link https://github.com/WordPress/gutenberg/tree/trunk/packages/block-serialization-default-parser block-serialization-default-parser} + * @see {@link https://github.com/WordPress/gutenberg/tree/trunk/packages/block-serialization-spec-parser block-serialization-spec-parser} * - * @param {WPRawBlock} rawBlock A block node as returned by a valid parser. - * @param {Options} [options={}] Serialization options. + * @param {BlockNode} rawBlock A block node as returned by a valid parser. + * @param {BlockSerializationOptions=} options Serialization options. * * @return {string} An HTML string representing a block. */ diff --git a/packages/blocks/src/api/registration.js b/packages/blocks/src/api/registration.js index 6633adf40050c..4223d94e14370 100644 --- a/packages/blocks/src/api/registration.js +++ b/packages/blocks/src/api/registration.js @@ -14,116 +14,26 @@ import { store as blocksStore } from '../store'; import { unlock } from '../lock-unlock'; /** - * An icon type definition. One of a Dashicon slug, an element, - * or a component. - * - * @typedef {(string|Element|Component)} WPIcon - * - * @see https://developer.wordpress.org/resource/dashicons/ - */ - -/** - * Render behavior of a block type icon; one of a Dashicon slug, an element, - * or a component. - * - * @typedef {WPIcon} WPBlockTypeIconRender - */ - -/** - * An object describing a normalized block type icon. - * - * @typedef {Object} WPBlockTypeIconDescriptor - * - * @property {WPBlockTypeIconRender} src Render behavior of the icon, - * one of a Dashicon slug, an - * element, or a component. - * @property {string} background Optimal background hex string - * color when displaying icon. - * @property {string} foreground Optimal foreground hex string - * color when displaying icon. - * @property {string} shadowColor Optimal shadow hex string - * color when displaying icon. - */ - -/** - * Value to use to render the icon for a block type in an editor interface, - * either a Dashicon slug, an element, a component, or an object describing - * the icon. - * - * @typedef {(WPBlockTypeIconDescriptor|WPBlockTypeIconRender)} WPBlockTypeIcon + * @typedef {import('../types').BlockCollection} BlockCollection + * @typedef {import('../types').BlockConfiguration} BlockConfiguration + * @typedef {import('../types').BlockIcon} BlockIcon + * @typedef {import('../types').BlockIconRenderer} BlockIconRenderer + * @typedef {import('../types').Block} Block + * @typedef {import('../types').BlockVariation} BlockVariation + * @typedef {import('../types').BlockVariationScope} BlockVariationScope + * @typedef {import('../types').BlockStyle} BlockStyle + * @typedef {import('../types').BlockSupports} BlockSupports + * @typedef {import('../types').BlockType} BlockType */ -/** - * Named block variation scopes. - * - * @typedef {'block'|'inserter'|'transform'} WPBlockVariationScope - */ +export const serverSideBlockDefinitions = {}; /** - * An object describing a variation defined for the block type. - * - * @typedef {Object} WPBlockVariation + * Object type guard. * - * @property {string} name The unique and machine-readable name. - * @property {string} title A human-readable variation title. - * @property {string} [description] A detailed variation description. - * @property {string} [category] Block type category classification, - * used in search interfaces to arrange - * block types by category. - * @property {WPIcon} [icon] An icon helping to visualize the variation. - * @property {boolean} [isDefault] Indicates whether the current variation is - * the default one. Defaults to `false`. - * @property {Object} [attributes] Values which override block attributes. - * @property {Array[]} [innerBlocks] Initial configuration of nested blocks. - * @property {Object} [example] Example provides structured data for - * the block preview. You can set to - * `undefined` to disable the preview shown - * for the block type. - * @property {WPBlockVariationScope[]} [scope] The list of scopes where the variation - * is applicable. When not provided, it - * assumes all available scopes. - * @property {string[]} [keywords] An array of terms (which can be translated) - * that help users discover the variation - * while searching. - * @property {Function|string[]} [isActive] This can be a function or an array of block attributes. - * Function that accepts a block's attributes and the - * variation's attributes and determines if a variation is active. - * This function doesn't try to find a match dynamically based - * on all block's attributes, as in many cases some attributes are irrelevant. - * An example would be for `embed` block where we only care - * about `providerNameSlug` attribute's value. - * We can also use a `string[]` to tell which attributes - * should be compared as a shorthand. Each attributes will - * be matched and the variation will be active if all of them are matching. + * @param {*} object The value to verify as a Record. + * @return { object is Record} Whether or not `object` is a Record. */ - -/** - * Defined behavior of a block type. - * - * @typedef {Object} WPBlockType - * - * @property {string} name Block type's namespaced name. - * @property {string} title Human-readable block type label. - * @property {string} [description] A detailed block type description. - * @property {string} [category] Block type category classification, - * used in search interfaces to arrange - * block types by category. - * @property {WPBlockTypeIcon} [icon] Block type icon. - * @property {string[]} [keywords] Additional keywords to produce block - * type as result in search interfaces. - * @property {Object} [attributes] Block type attributes. - * @property {Component} [save] Optional component describing - * serialized markup structure of a - * block type. - * @property {Component} edit Component rendering an element to - * manipulate the attributes of a block - * in the context of an editor. - * @property {WPBlockVariation[]} [variations] The list of block variations. - * @property {Object} [example] Example provides structured data for - * the block preview. When not defined - * then no preview is shown. - */ - function isObject( object ) { return object !== null && typeof object === 'object'; } @@ -131,7 +41,7 @@ function isObject( object ) { /** * Sets the server side block definition of blocks. * - * @param {Object} definitions Server-side block definitions + * @param {Record} definitions Server-side block definitions */ // eslint-disable-next-line camelcase export function unstable__bootstrapServerSideBlockDefinitions( definitions ) { @@ -144,8 +54,8 @@ export function unstable__bootstrapServerSideBlockDefinitions( definitions ) { /** * Gets block settings from metadata loaded from `block.json` file. * - * @param {Object} metadata Block metadata loaded from `block.json`. - * @param {string} metadata.textdomain Textdomain to use with translations. + * @param {Object} metadata Block metadata loaded from `block.json`. + * @param {string=} metadata.textdomain Textdomain to use with translations. * * @return {Object} Block settings. */ @@ -201,8 +111,11 @@ function getBlockSettingsFromMetadata( { textdomain, ...metadata } ) { * For more in-depth information on registering a custom block see the * [Create a block tutorial](https://developer.wordpress.org/block-editor/getting-started/create-block/). * - * @param {string|Object} blockNameOrMetadata Block type name or its metadata. - * @param {Object} settings Block settings. + * @template {import('../types').BlockConfiguration} BlockMetadata + * @template {Record} Attributes + * + * @param {string|BlockMetadata} blockNameOrMetadata Block type name or its metadata. + * @param {(Partial|BlockMetadata)=} settings Block settings. * * @example * ```js @@ -216,7 +129,7 @@ function getBlockSettingsFromMetadata( { textdomain, ...metadata } ) { * } ); * ``` * - * @return {WPBlockType | undefined} The block, if it has been successfully registered; + * @return {BlockType|undefined} The block, if it has been successfully registered; * otherwise `undefined`. */ export function registerBlockType( blockNameOrMetadata, settings ) { @@ -309,10 +222,8 @@ function translateBlockSettingUsingI18nSchema( /** * Registers a new block collection to group blocks in the same namespace in the inserter. * - * @param {string} namespace The namespace to group blocks by in the inserter; corresponds to the block namespace. - * @param {Object} settings The block collection settings. - * @param {string} settings.title The title to display in the block inserter. - * @param {Object} [settings.icon] The icon to display in the block inserter. + * @param {string} namespace The namespace to group blocks by in the inserter; corresponds to the block namespace. + * @param {BlockCollection} settings The block collection settings. * * @example * ```js @@ -375,7 +286,7 @@ export function unregisterBlockCollection( namespace ) { * }; * ``` * - * @return {WPBlockType | undefined} The previous block value, if it has been successfully + * @return {BlockType|undefined} The previous block value, if it has been successfully * unregistered; otherwise `undefined`. */ export function unregisterBlockType( name ) { @@ -401,7 +312,7 @@ export function setFreeformContentHandlerName( blockName ) { * Retrieves name of block handling non-block content, or undefined if no * handler has been defined. * - * @return {?string} Block name. + * @return {string|undefined} Block name. */ export function getFreeformContentHandlerName() { return select( blocksStore ).getFreeformFallbackBlockName(); @@ -410,7 +321,7 @@ export function getFreeformContentHandlerName() { /** * Retrieves name of block used for handling grouping interactions. * - * @return {?string} Block name. + * @return {string|undefined} Block name. */ export function getGroupingBlockName() { return select( blocksStore ).getGroupingBlockName(); @@ -429,7 +340,7 @@ export function setUnregisteredTypeHandlerName( blockName ) { * Retrieves name of block handling unregistered block types, or undefined if no * handler has been defined. * - * @return {?string} Block name. + * @return {string|undefined} Block name. */ export function getUnregisteredTypeHandlerName() { return select( blocksStore ).getUnregisteredFallbackBlockName(); @@ -488,7 +399,7 @@ export function setGroupingBlockName( name ) { /** * Retrieves the default block name. * - * @return {?string} Block name. + * @return {string|undefined} Block name. */ export function getDefaultBlockName() { return select( blocksStore ).getDefaultBlockName(); @@ -499,7 +410,7 @@ export function getDefaultBlockName() { * * @param {string} name Block name. * - * @return {?Object} Block type. + * @return {BlockType|undefined} Block type. */ export function getBlockType( name ) { return select( blocksStore )?.getBlockType( name ); @@ -508,7 +419,7 @@ export function getBlockType( name ) { /** * Returns all registered blocks. * - * @return {Array} Block settings. + * @return {BlockType[]} Block settings. */ export function getBlockTypes() { return select( blocksStore ).getBlockTypes(); @@ -517,12 +428,12 @@ export function getBlockTypes() { /** * Returns the block support value for a feature, if defined. * - * @param {(string|Object)} nameOrType Block name or type object - * @param {string} feature Feature to retrieve - * @param {*} defaultSupports Default value to return if not - * explicitly defined + * @param {string|BlockType} nameOrType Block name or type object + * @param {keyof BlockSupports} feature Feature to retrieve + * @param {*} defaultSupports Default value to return if not + * explicitly defined * - * @return {?*} Block support value + * @return {*} Block support value */ export function getBlockSupport( nameOrType, feature, defaultSupports ) { return select( blocksStore ).getBlockSupport( @@ -535,10 +446,10 @@ export function getBlockSupport( nameOrType, feature, defaultSupports ) { /** * Returns true if the block defines support for a feature, or false otherwise. * - * @param {(string|Object)} nameOrType Block name or type object. - * @param {string} feature Feature to test. - * @param {boolean} defaultSupports Whether feature is supported by - * default if not explicitly defined. + * @param {string|BlockType} nameOrType Block name or type object. + * @param {keyof BlockSupports} feature Feature to test. + * @param {boolean} defaultSupports Whether feature is supported by + * default if not explicitly defined. * * @return {boolean} Whether block supports feature. */ @@ -555,7 +466,7 @@ export function hasBlockSupport( nameOrType, feature, defaultSupports ) { * special block type that is used to point to a global block stored via the * API. * - * @param {Object} blockOrType Block or Block Type to test. + * @param { BlockType|Block} blockOrType Block or Block Type to test. * * @return {boolean} Whether the given block is a reusable block. */ @@ -568,7 +479,7 @@ export function isReusableBlock( blockOrType ) { * special block type that allows composing a page template out of reusable * design elements. * - * @param {Object} blockOrType Block or Block Type to test. + * @param {Block|BlockType} blockOrType Block or Block Type to test. * * @return {boolean} Whether the given block is a template part. */ @@ -581,7 +492,7 @@ export function isTemplatePart( blockOrType ) { * * @param {string} blockName Name of block (example: “latest-posts”). * - * @return {Array} Array of child block names. + * @return {string[]} Array of child block names. */ export const getChildBlockNames = ( blockName ) => { return select( blocksStore ).getChildBlockNames( blockName ); @@ -616,8 +527,8 @@ export const hasChildBlocksWithInserterSupport = ( blockName ) => { * For more information on connecting the styles with CSS * [the official documentation](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-styles/#styles). * - * @param {string} blockName Name of block (example: “core/latest-posts”). - * @param {Object} styleVariation Object containing `name` which is the class name applied to the block and `label` which identifies the variation to the user. + * @param {string} blockName Name of block (example: “core/latest-posts”). + * @param {BlockStyle} styleVariation Object containing `name` which is the class name applied to the block and `label` which identifies the variation to the user. * * @example * ```js @@ -681,10 +592,10 @@ export const unregisterBlockStyle = ( blockName, styleVariationName ) => { * * @ignore * - * @param {string} blockName Name of block (example: “core/columns”). - * @param {WPBlockVariationScope} [scope] Block variation scope name. + * @param {string} blockName Name of block (example: “core/columns”). + * @param {BlockVariationScope=} scope Block variation scope name. * - * @return {(WPBlockVariation[]|void)} Block variations. + * @return {BlockVariation[]|undefined)} Block variations. */ export const getBlockVariations = ( blockName, scope ) => { return select( blocksStore ).getBlockVariations( blockName, scope ); @@ -696,8 +607,8 @@ export const getBlockVariations = ( blockName, scope ) => { * For more information on block variations see * [the official documentation ](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-variations/). * - * @param {string} blockName Name of the block (example: “core/columns”). - * @param {WPBlockVariation} variation Object describing a block variation. + * @param {string} blockName Name of the block (example: “core/columns”). + * @param {BlockVariation} variation Object describing a block variation. * * @example * ```js diff --git a/packages/blocks/src/api/serializer.js b/packages/blocks/src/api/serializer.js index 5883f47536431..89a0b0c8bab37 100644 --- a/packages/blocks/src/api/serializer.js +++ b/packages/blocks/src/api/serializer.js @@ -22,12 +22,13 @@ import { import { serializeRawBlock } from './parser/serialize-raw-block'; import { isUnmodifiedDefaultBlock, normalizeBlockType } from './utils'; -/** @typedef {import('./parser').WPBlock} WPBlock */ - /** - * @typedef {Object} WPBlockSerializationOptions Serialization Options. - * - * @property {boolean} isInnerBlocks Whether we are serializing inner blocks. + * @typedef {import('react').ReactElement} Element + * @typedef {import('react').HTMLAttributes} HTMLAttributes + * @typedef {import('../types').Block} Block + * @typedef {import('../types').BlockType} BlockType + * @typedef {import('../types').BlockAttributes} BlockAttributes + * @typedef {import('./types').BlockSerializationOptions} BlockSerializationOptions */ /** @@ -111,15 +112,24 @@ export function getInnerBlocksProps( props = {} ) { return { ...props, children }; } +/** + * Return type of {@link getSaveElement}. + * + * @typedef BlockSaveResult + * @property {Element} element Block save result. + * @property {Block} blockType Block type definition. + * @property {BlockAttributes} attributes Block attributes. + */ + /** * Given a block type containing a save render implementation and attributes, returns the * enhanced element to be saved or string when raw HTML expected. * - * @param {string|Object} blockTypeOrName Block type or name. - * @param {Object} attributes Block attributes. - * @param {?Array} innerBlocks Nested blocks. + * @param {BlockType|string} blockTypeOrName Block type or name. + * @param {BlockAttributes} attributes Block attributes. + * @param {Block[]=} innerBlocks Nested blocks. * - * @return {Object|string} Save element or raw HTML string. + * @return {BlockSaveResult|string} Save element or raw HTML string. */ export function getSaveElement( blockTypeOrName, @@ -155,9 +165,9 @@ export function getSaveElement( /** * Filters the props applied to the block save result element. * - * @param {Object} props Props applied to save element. - * @param {WPBlock} blockType Block type definition. - * @param {Object} attributes Block attributes. + * @param {Object} props Props applied to save element. + * @param {BlockType} blockType Block type definition. + * @param {BlockAttributes} attributes Block attributes. */ const props = applyFilters( 'blocks.getSaveContent.extraProps', @@ -174,10 +184,11 @@ export function getSaveElement( /** * Filters the save result of a block during serialization. * - * @param {Element} element Block save result. - * @param {WPBlock} blockType Block type definition. - * @param {Object} attributes Block attributes. + * @param {Element} element Block save result. + * @param {Block} blockType Block type definition. + * @param {BlockAttributes} attributes Block attributes. */ + return applyFilters( 'blocks.getSaveElement', element, @@ -190,9 +201,9 @@ export function getSaveElement( * Given a block type containing a save render implementation and attributes, returns the * static markup to be saved. * - * @param {string|Object} blockTypeOrName Block type or name. - * @param {Object} attributes Block attributes. - * @param {?Array} innerBlocks Nested blocks. + * @param {BlockType|string} blockTypeOrName Block type or name. + * @param {BlockAttributes} attributes Block attributes. + * @param {Block[]=} innerBlocks Nested blocks. * * @return {string} Save content. */ @@ -215,10 +226,10 @@ export function getSaveContent( blockTypeOrName, attributes, innerBlocks ) { * This function returns only those attributes which are needed to persist and * which cannot be matched from the block content. * - * @param {Object} blockType Block type. - * @param {Object} attributes Attributes from in-memory block data. + * @param {BlockType} blockType Block type. + * @param {BlockAttributes} attributes Attributes from in-memory block data. * - * @return {Object} Subset of attributes for comment serialization. + * @return {Partial} Subset of attributes for comment serialization. */ export function getCommentAttributes( blockType, attributes ) { return Object.entries( blockType.attributes ?? {} ).reduce( @@ -256,7 +267,7 @@ export function getCommentAttributes( blockType, attributes ) { * Given an attributes object, returns a string in the serialized attributes * format prepared for post content. * - * @param {Object} attributes Attributes object. + * @param {BlockAttributes} attributes Attributes object. * * @return {string} Serialized attributes. */ @@ -282,7 +293,7 @@ export function serializeAttributes( attributes ) { /** * Given a block object, returns the Block's Inner HTML markup. * - * @param {Object} block Block instance. + * @param {Block} block Block instance. * * @return {string} HTML. */ @@ -309,9 +320,9 @@ export function getBlockInnerHTML( block ) { /** * Returns the content of a block, including comment delimiters. * - * @param {string} rawBlockName Block name. - * @param {Object} attributes Block attributes. - * @param {string} content Block save content. + * @param {string} rawBlockName Block name. + * @param {BlockAttributes} attributes Block attributes. + * @param {string} content Block save content. * * @return {string} Comment-delimited block content. */ @@ -347,8 +358,8 @@ export function getCommentDelimitedContent( * Returns the content of a block, including comment delimiters, determining * serialized attributes and content form from the current state of the block. * - * @param {WPBlock} block Block instance. - * @param {WPBlockSerializationOptions} options Serialization options. + * @param {Block} block Block instance. + * @param {BlockSerializationOptions} options Serialization options. * * @return {string} Serialized block. */ @@ -376,6 +387,13 @@ export function serializeBlock( block, { isInnerBlocks = false } = {} ) { return getCommentDelimitedContent( blockName, saveAttributes, saveContent ); } +/** + * Serialize and clean blocks to handle empty posts and backward compatibility. + * + * @param {Block[]} blocks The blocks to process. + * + * @return {string} The serialized result of rendering the `blocks`. + */ export function __unstableSerializeAndClean( blocks ) { // A single unmodified default block is assumed to // be equivalent to an empty post. @@ -402,8 +420,8 @@ export function __unstableSerializeAndClean( blocks ) { /** * Takes a block or set of blocks and returns the serialized post content. * - * @param {Array} blocks Block(s) to serialize. - * @param {WPBlockSerializationOptions} options Serialization options. + * @param {Block[]} blocks Block(s) to serialize. + * @param {BlockSerializationOptions=} options Serialization options. * * @return {string} The post content. */ diff --git a/packages/blocks/src/api/templates.js b/packages/blocks/src/api/templates.js index bc76218892688..1a5cef3f441e2 100644 --- a/packages/blocks/src/api/templates.js +++ b/packages/blocks/src/api/templates.js @@ -10,11 +10,16 @@ import { convertLegacyBlockNameAndAttributes } from './parser/convert-legacy-blo import { createBlock } from './factory'; import { getBlockType } from './registration'; +/** + * @typedef {import('../types').Block} Block + * @typedef {import('../types').InnerBlockTemplate} InnerBlockTemplate + */ + /** * Checks whether a list of blocks matches a template by comparing the block names. * - * @param {Array} blocks Block list. - * @param {Array} template Block template. + * @param {Block[]} blocks Block list. + * @param {InnerBlockTemplate[]} template Block template. * * @return {boolean} Whether the list of blocks matches a templates. */ @@ -39,10 +44,10 @@ export function doBlocksMatchTemplate( blocks = [], template = [] ) { * (If it has the same name) and if doesn't match, we create a new block based on the template. * Extra blocks not present in the template are removed. * - * @param {Array} blocks Block list. - * @param {Array} template Block template. + * @param {Block[]} blocks Block list. + * @param {InnerBlockTemplate[]=} template Block template. * - * @return {Array} Updated Block list. + * @return {Block[]} Updated Block list. */ export function synchronizeBlocksWithTemplate( blocks = [], template ) { // If no template is provided, return blocks unmodified. diff --git a/packages/blocks/src/api/types.ts b/packages/blocks/src/api/types.ts new file mode 100644 index 0000000000000..8629ec0577172 --- /dev/null +++ b/packages/blocks/src/api/types.ts @@ -0,0 +1,55 @@ +/** + * Describes options for Block serialization. + * + * Used by the Block [serializer](./serializer.js). + * + * @public + */ +export type BlockSerializationOptions = { + /** + * Whether to output HTML comments around blocks. + */ + isCommentDelimited?: boolean; + + /** + * Whether the serialization process has descended into the inner blocks. + */ + isInnerBlocks?: boolean; + + /** + * If a block is migrated from a deprecated version, skip logging the migration details. + * + * @internal + */ + __unstableSkipMigrationLogs?: boolean; + + /** + * Whether to skip autop when processing freeform content. + * + * @internal + */ + __unstableSkipAutop?: boolean; +}; + +/** + * Describes options for Block parsing. + * + * Used by the block [parser](./parser/index.js). + * + * @public + */ +export type BlockParseOptions = { + /** + * If a block is migrated from a deprecated version, skip logging the migration details. + * + * @internal + */ + __unstableSkipMigrationLogs?: boolean; + + /** + * Whether to skip autop when processing freeform content. + * + * @internal + */ + __unstableSkipAutop?: boolean; +}; diff --git a/packages/blocks/src/api/utils.js b/packages/blocks/src/api/utils.js index 0d17836faea7e..9d95324c0f864 100644 --- a/packages/blocks/src/api/utils.js +++ b/packages/blocks/src/api/utils.js @@ -19,6 +19,16 @@ import { RichTextData } from '@wordpress/rich-text'; import { BLOCK_ICON_DEFAULT } from './constants'; import { getBlockType, getDefaultBlockName } from './registration'; +/** + * @typedef {import('../types').Block} Block + * @typedef {import('../types').BlockType} BlockType + * @typedef {import('../types').AxialDirection} AxialDirection + * @typedef {import('../types').BlockAttributes} BlockAttributes + * @typedef {import('../types').BlockIcon} BlockIcon + * @typedef {import('../types').BlockIconNormalized} BlockIconNormalized + * @typedef {import('../types').BlockIconRenderer} BlockIconRenderer + */ + extend( [ namesPlugin, a11yPlugin ] ); /** @@ -33,7 +43,7 @@ const ICON_COLORS = [ '#191e23', '#f8f9f9' ]; * Determines whether the block's attributes are equal to the default attributes * which means the block is unmodified. * - * @param {WPBlock} block Block Object + * @param {Block} block Block Object * * @return {boolean} Whether the block is an unmodified block. */ @@ -64,7 +74,7 @@ export function isUnmodifiedBlock( block ) { * Determines whether the block is a default block and its attributes are equal * to the default attributes which means the block is unmodified. * - * @param {WPBlock} block Block Object + * @param {Block} block Block Object * * @return {boolean} Whether the block is an unmodified default block. */ @@ -77,7 +87,7 @@ export function isUnmodifiedDefaultBlock( block ) { * * @param {*} icon Parameter to be checked. * - * @return {boolean} True if the parameter is a valid icon and false otherwise. + * @return {icon is BlockIconRenderer} True if the parameter is a valid icon and false otherwise. */ export function isValidIcon( icon ) { @@ -95,11 +105,11 @@ export function isValidIcon( icon ) { * and returns a new icon object that is normalized so we can rely on just on possible icon structure * in the codebase. * - * @param {WPBlockTypeIconRender} icon Render behavior of a block type icon; - * one of a Dashicon slug, an element, or a - * component. + * @param {BlockIcon} icon Render behavior of a block type icon; + * one of a Dashicon slug, an element, or a + * component. * - * @return {WPBlockTypeIconDescriptor} Object describing the icon. + * @return {BlockIconNormalized} Object describing the icon. */ export function normalizeIconObject( icon ) { icon = icon || BLOCK_ICON_DEFAULT; @@ -133,9 +143,9 @@ export function normalizeIconObject( icon ) { * it converts it to the matching block type object. * It passes the original object otherwise. * - * @param {string|Object} blockTypeOrName Block type or name. + * @param {BlockType|string} blockTypeOrName Block type or name. * - * @return {?Object} Block type. + * @return {BlockType|undefined} Block type. */ export function normalizeBlockType( blockTypeOrName ) { if ( typeof blockTypeOrName === 'string' ) { @@ -149,9 +159,9 @@ export function normalizeBlockType( blockTypeOrName ) { * Get the label for the block, usually this is either the block title, * or the value of the block's `label` function when that's specified. * - * @param {Object} blockType The block type. - * @param {Object} attributes The values of the block's attributes. - * @param {Object} context The intended use for the label. + * @param {BlockType} blockType The block type. + * @param {BlockAttributes} attributes The values of the block's attributes. + * @param {Object} context The intended use for the label. * * @return {string} The block label. */ @@ -173,10 +183,10 @@ export function getBlockLabel( blockType, attributes, context = 'visual' ) { * than the visual label and includes the block title and the value of the * `getLabel` function if it's specified. * - * @param {?Object} blockType The block type. - * @param {Object} attributes The values of the block's attributes. - * @param {?number} position The position of the block in the block list. - * @param {string} [direction='vertical'] The direction of the block layout. + * @param {BlockType|undefined} blockType The block type. + * @param {BlockAttributes} attributes The values of the block's attributes. + * @param {number=} position The position of the block in the block list. + * @param {AxialDirection=} direction The direction of the block layout. * * @return {string} The block label. */ @@ -265,9 +275,9 @@ export function getDefault( attributeSchema ) { * Ensure attributes contains only values defined by block type, and merge * default values for missing attributes. * - * @param {string} name The block's name. - * @param {Object} attributes The block's attributes. - * @return {Object} The sanitized attributes. + * @param {string} name The block's name. + * @param {BlockAttributes} attributes The block's attributes. + * @return {BlockAttributes} The sanitized attributes. */ export function __experimentalSanitizeBlockAttributes( name, attributes ) { // Get the type definition associated with a registered block. diff --git a/packages/blocks/src/api/validation/index.js b/packages/blocks/src/api/validation/index.js index 29b8a08771833..61412b815bad3 100644 --- a/packages/blocks/src/api/validation/index.js +++ b/packages/blocks/src/api/validation/index.js @@ -21,10 +21,21 @@ import { } from '../registration'; import { normalizeBlockType } from '../utils'; -/** @typedef {import('../parser').WPBlock} WPBlock */ -/** @typedef {import('../registration').WPBlockType} WPBlockType */ -/** @typedef {import('./logger').LoggerItem} LoggerItem */ +/** + * @typedef {import('simple-html-tokenizer').Token} Token + * @typedef {import('../../types').BlockAttributes} BlockAttributes + * @typedef {import('../../types').Block} Block + * @typedef {import('../../types').BlockType} BlockType + * @typedef {import('./logger').LoggerItem} LoggerItem + */ +/** + * Directly returns the value provided. + * + * @template Value + * @param {Value} x The input value. + * @return {Value} The output value. + */ const identity = ( x ) => x; /** @@ -61,7 +72,7 @@ const REGEXP_STYLE_URL_TYPE = /^url\s*\(['"\s]*(.*?)['"\s]*\)$/; * [ tr.firstChild.textContent.trim() ]: true * } ), {} ) ).sort(); * - * @type {Array} + * @type {string[]} */ const BOOLEAN_ATTRIBUTES = [ 'allowfullscreen', @@ -108,7 +119,7 @@ const BOOLEAN_ATTRIBUTES = [ * [ tr.firstChild.textContent.trim() ]: true * } ), {} ) ).sort(); * - * @type {Array} + * @type {string[]} */ const ENUMERATED_ATTRIBUTES = [ 'autocapitalize', @@ -139,7 +150,7 @@ const ENUMERATED_ATTRIBUTES = [ * Meaningful attributes are those who cannot be safely ignored when omitted in * one HTML markup string and not another. * - * @type {Array} + * @type {string[]} */ const MEANINGFUL_ATTRIBUTES = [ ...BOOLEAN_ATTRIBUTES, @@ -151,7 +162,7 @@ const MEANINGFUL_ATTRIBUTES = [ * behavior for consideration in text token equivalence, carefully ordered from * least-to-most expensive operations. * - * @type {Array} + * @type {Array<(value: string) => string>} */ const TEXT_NORMALIZATIONS = [ identity, getTextWithCollapsedWhitespace ]; @@ -235,7 +246,7 @@ export class DecodeEntityParser { * * @param {string} entity Entity fragment discovered in HTML. * - * @return {string | undefined} Entity substitute value. + * @return {string|void} Entity substitute value. */ parse( entity ) { if ( isValidCharacterReference( entity ) ) { @@ -279,9 +290,9 @@ export function getTextWithCollapsedWhitespace( text ) { * * @see MEANINGFUL_ATTRIBUTES * - * @param {Object} token StartTag token. + * @param {Token} token StartTag token. * - * @return {Array[]} Attribute pairs. + * @return {[string, string][]} Attribute pairs. */ export function getMeaningfulAttributePairs( token ) { return token.attributes.filter( ( pair ) => { @@ -298,8 +309,8 @@ export function getMeaningfulAttributePairs( token ) { * Returns true if two text tokens (with `chars` property) are equivalent, or * false otherwise. * - * @param {Object} actual Actual token. - * @param {Object} expected Expected token. + * @param {Token} actual Actual token. + * @param {Token} expected Expected token. * @param {Object} logger Validation logger object. * * @return {boolean} Whether two text tokens are equivalent. @@ -438,9 +449,9 @@ export const isEqualAttributesOfName = { * Given two sets of attribute tuples, returns true if the attribute sets are * equivalent. * - * @param {Array[]} actual Actual attributes tuples. - * @param {Array[]} expected Expected attributes tuples. - * @param {Object} logger Validation logger object. + * @param {[string, string][]} actual Actual attributes tuples. + * @param {[string, string][]} expected Expected attributes tuples. + * @param {Object} logger Validation logger object. * * @return {boolean} Whether attributes are equivalent. */ @@ -512,7 +523,7 @@ export function isEqualTagAttributePairs( /** * Token-type-specific equality handlers * - * @type {Object} + * @type {Record boolean>} */ export const isEqualTokensOfType = { StartTag: ( actual, expected, logger = createLogger() ) => { @@ -546,9 +557,9 @@ export const isEqualTokensOfType = { * * Mutates the tokens array. * - * @param {Object[]} tokens Set of tokens to search. + * @param {Token[]} tokens Set of tokens to search. * - * @return {Object | undefined} Next non-whitespace token. + * @return {Token|void} Next non-whitespace token. */ export function getNextNonWhitespaceToken( tokens ) { let token; @@ -570,7 +581,7 @@ export function getNextNonWhitespaceToken( tokens ) { * @param {string} html HTML string to tokenize. * @param {Object} logger Validation logger object. * - * @return {Object[]|null} Array of valid tokenized HTML elements, or null on error + * @return {Token[]|null} Array of valid tokenized HTML elements, or null on error */ function getHTMLTokens( html, logger = createLogger() ) { try { @@ -585,8 +596,8 @@ function getHTMLTokens( html, logger = createLogger() ) { /** * Returns true if the next HTML token closes the current token. * - * @param {Object} currentToken Current token to compare with. - * @param {Object|undefined} nextToken Next token to compare against. + * @param {Token} currentToken Current token to compare with. + * @param {Token=} nextToken Next token to compare against. * * @return {boolean} true if `nextToken` closes `currentToken`, false otherwise */ @@ -702,22 +713,8 @@ export function isEquivalentHTML( actual, expected, logger = createLogger() ) { * with assumed attributes, the content matches the original value. If block is * invalid, this function returns all validations issues as well. * - * @param {string|Object} blockTypeOrName Block type. - * @param {Object} attributes Parsed block attributes. - * @param {string} originalBlockContent Original block content. - * @param {Object} logger Validation logger object. - * - * @return {Object} Whether block is valid and contains validation messages. - */ - -/** - * Returns an object with `isValid` property set to `true` if the parsed block - * is valid given the input content. A block is considered valid if, when serialized - * with assumed attributes, the content matches the original value. If block is - * invalid, this function returns all validations issues as well. - * - * @param {WPBlock} block block object. - * @param {WPBlockType|string} [blockTypeOrName = block.name] Block type or name, inferred from block if not given. + * @param {Block} block block object. + * @param {(BlockType|string)=} blockTypeOrName Block type or name, inferred from block if not given. * * @return {[boolean,Array]} validation results. */ @@ -773,9 +770,9 @@ export function validateBlock( block, blockTypeOrName = block.name ) { * * @deprecated Use validateBlock instead to avoid data loss. * - * @param {string|Object} blockTypeOrName Block type. - * @param {Object} attributes Parsed block attributes. - * @param {string} originalBlockContent Original block content. + * @param {BlockType|string} blockTypeOrName Block type. + * @param {BlockAttributes} attributes Parsed block attributes. + * @param {string} originalBlockContent Original block content. * * @return {boolean} Whether block is valid. */ diff --git a/packages/blocks/src/deprecated.js b/packages/blocks/src/deprecated.js index b3d01d1167bf5..8f28355a9b922 100644 --- a/packages/blocks/src/deprecated.js +++ b/packages/blocks/src/deprecated.js @@ -9,6 +9,9 @@ import deprecated from '@wordpress/deprecated'; * * @deprecated * + * @template T + * @typedef {import('react').ComponentType} Component + * * @param {Component} OriginalComponent The component to enhance. * @return {Component} The same component. */ diff --git a/packages/blocks/src/index.js b/packages/blocks/src/index.js index 7164341c9fe4c..76eb2a690d763 100644 --- a/packages/blocks/src/index.js +++ b/packages/blocks/src/index.js @@ -11,3 +11,4 @@ export { store } from './store'; export * from './api'; export * from './deprecated'; +export * from './types'; diff --git a/packages/blocks/src/store/actions.js b/packages/blocks/src/store/actions.js index d3bd71c067ebe..6c500525bcd4d 100644 --- a/packages/blocks/src/store/actions.js +++ b/packages/blocks/src/store/actions.js @@ -8,9 +8,17 @@ import deprecated from '@wordpress/deprecated'; */ import { processBlockType } from './process-block-type'; -/** @typedef {import('../api/registration').WPBlockVariation} WPBlockVariation */ -/** @typedef {import('../api/registration').WPBlockType} WPBlockType */ -/** @typedef {import('./reducer').WPBlockCategory} WPBlockCategory */ +/** + * @typedef {import('../types').BlockAttributes} BlockAttributes + * @typedef {import('../types').BlockCategory} BlockCategory + * @typedef {import('../types').BlockCollection} BlockCollection + * @typedef {import('../types').BlockDeprecation} BlockDeprecation + * @typedef {import('../types').BlockIconRenderer} BlockIconRenderer + * @typedef {import('../types').BlockVariation} BlockVariation + * @typedef {import('../types').BlockStyle} BlockStyle + * @typedef {import('../types').BlockType} BlockType + * @typedef {import('../types').BlockTypeCategory} BlockTypeCategory + */ /** * Returns an action object used in signalling that block types have been added. @@ -18,7 +26,7 @@ import { processBlockType } from './process-block-type'; * * @ignore * - * @param {WPBlockType|WPBlockType[]} blockTypes Object or array of objects representing blocks to added. + * @param {BlockType|BlockType[]} blockTypes Object or array of objects representing blocks to added. * * * @return {Object} Action object. @@ -98,8 +106,8 @@ export function removeBlockTypes( names ) { * Returns an action object used in signalling that new block styles have been added. * Ignored from documentation as the recommended usage for this action through registerBlockStyle from @wordpress/blocks. * - * @param {string} blockName Block name. - * @param {Array|Object} styles Block style object or array of block style objects. + * @param {string} blockName Block name. + * @param {BlockStyle|BlockStyle[]} styles Block style object or array of block style objects. * * @ignore * @@ -119,8 +127,8 @@ export function addBlockStyles( blockName, styles ) { * * @ignore * - * @param {string} blockName Block name. - * @param {Array|string} styleNames Block style names or array of block style names. + * @param {string} blockName Block name. + * @param {string|string[]} styleNames Block style names or array of block style names. * * @return {Object} Action object. */ @@ -138,8 +146,8 @@ export function removeBlockStyles( blockName, styleNames ) { * * @ignore * - * @param {string} blockName Block name. - * @param {WPBlockVariation|WPBlockVariation[]} variations Block variations. + * @param {string} blockName Block name. + * @param {BlockVariation|BlockVariation[]} variations Block variations. * * @return {Object} Action object. */ @@ -250,7 +258,7 @@ export function setGroupingBlockName( name ) { * * @ignore * - * @param {WPBlockCategory[]} categories Block categories. + * @param {BlockCategory[]} categories Block categories. * * @return {Object} Action object. */ @@ -267,8 +275,8 @@ export function setCategories( categories ) { * * @ignore * - * @param {string} slug Block category slug. - * @param {Object} category Object containing the category properties that should be updated. + * @param {string} slug Block category slug. + * @param {Partial} category Object containing the category properties that should be updated. * * @return {Object} Action object. */ @@ -286,9 +294,9 @@ export function updateCategory( slug, category ) { * * @ignore * - * @param {string} namespace The namespace of the blocks to put in the collection - * @param {string} title The title to display in the block inserter - * @param {Object} icon (optional) The icon to display in the block inserter + * @param {string} namespace The namespace of the blocks to put in the collection + * @param {string} title The title to display in the block inserter + * @param {BlockIconRenderer} icon (optional) The icon to display in the block inserter * * @return {Object} Action object. */ diff --git a/packages/blocks/src/store/private-selectors.js b/packages/blocks/src/store/private-selectors.js index f2acf9c105184..c54364cecf140 100644 --- a/packages/blocks/src/store/private-selectors.js +++ b/packages/blocks/src/store/private-selectors.js @@ -35,9 +35,9 @@ const ROOT_BLOCK_SUPPORTS = [ /** * Filters the list of supported styles for a given element. * - * @param {string[]} blockSupports list of supported styles. - * @param {string|undefined} name block name. - * @param {string|undefined} element element name. + * @param {string[]} blockSupports list of supported styles. + * @param {string=} name block name. + * @param {string=} element element name. * * @return {string[]} filtered list of supported styles. */ diff --git a/packages/blocks/src/store/reducer.js b/packages/blocks/src/store/reducer.js index 91f061871f9e2..c9912abb38c12 100644 --- a/packages/blocks/src/store/reducer.js +++ b/packages/blocks/src/store/reducer.js @@ -15,16 +15,15 @@ import { __ } from '@wordpress/i18n'; import { omit } from '../api/utils'; /** - * @typedef {Object} WPBlockCategory - * - * @property {string} slug Unique category slug. - * @property {string} title Category label, for display in user interface. + * @typedef {import('../types').BlockCategory} BlockCategory + * @typedef {import('../types').BlockType} BlockType + * @typedef {import('./types').BlockStoreState} BlockStoreState */ /** * Default set of categories. * - * @type {WPBlockCategory[]} + * @type {BlockCategory[]} */ export const DEFAULT_CATEGORIES = [ { slug: 'text', title: __( 'Text' ) }, @@ -36,7 +35,13 @@ export const DEFAULT_CATEGORIES = [ { slug: 'reusable', title: __( 'Reusable blocks' ) }, ]; -// Key block types by their name. +/** + * Key block types by their name. + * + * @param {BlockType[]} types Block types of which to + * + * @return {Record} Block types collected into an object indexed by `name` property. + */ function keyBlockTypesByName( types ) { return types.reduce( ( newBlockTypes, block ) => ( { @@ -47,7 +52,13 @@ function keyBlockTypesByName( types ) { ); } -// Filter items to ensure they're unique by their name. +/** + * Filter items to ensure they're unique by their name. + * + * @template {{name: string}} Item + * @param {Item[]} items - Items to be filtered by `name` property. + * @return {Item[]} Filtered array of items. + */ function getUniqueItemsByName( items ) { return items.reduce( ( acc, currentItem ) => { if ( ! acc.some( ( item ) => item.name === currentItem.name ) ) { @@ -141,10 +152,10 @@ function bootstrappedBlockTypes( state = {}, action ) { * It's for internal use only. It allows recomputing the processed block types on-demand after block type filters * get added or removed. * - * @param {Object} state Current state. - * @param {Object} action Dispatched action. + * @param {BlockStoreState} state Current state. + * @param {Object} action Dispatched action. * - * @return {Object} Updated state. + * @return {BlockStoreState} Updated state. */ export function unprocessedBlockTypes( state = {}, action ) { switch ( action.type ) { @@ -164,10 +175,10 @@ export function unprocessedBlockTypes( state = {}, action ) { * Reducer managing the processed block types with all filters applied. * The state is derived from the `unprocessedBlockTypes` reducer. * - * @param {Object} state Current state. - * @param {Object} action Dispatched action. + * @param {BlockStoreState} state Current state. + * @param {Object} action Dispatched action. * - * @return {Object} Updated state. + * @return {BlockStoreState} Updated state. */ export function blockTypes( state = {}, action ) { switch ( action.type ) { @@ -186,10 +197,10 @@ export function blockTypes( state = {}, action ) { /** * Reducer managing the block styles. * - * @param {Object} state Current state. - * @param {Object} action Dispatched action. + * @param {BlockStoreState} state Current state. + * @param {Object} action Dispatched action. * - * @return {Object} Updated state. + * @return {BlockStoreState} Updated state. */ export function blockStyles( state = {}, action ) { switch ( action.type ) { @@ -238,10 +249,10 @@ export function blockStyles( state = {}, action ) { /** * Reducer managing the block variations. * - * @param {Object} state Current state. - * @param {Object} action Dispatched action. + * @param {BlockStoreState} state Current state. + * @param {Object} action Dispatched action. * - * @return {Object} Updated state. + * @return {BlockStoreState} Updated state. */ export function blockVariations( state = {}, action ) { switch ( action.type ) { @@ -297,7 +308,7 @@ export function blockVariations( state = {}, action ) { * * @param {string} setActionType Action type. * - * @return {Function} Reducer. + * @return {( state: string | null, action: Object ) => any} Reducer. */ export function createBlockNameSetterReducer( setActionType ) { return ( state = null, action ) => { @@ -332,10 +343,10 @@ export const groupingBlockName = createBlockNameSetterReducer( /** * Reducer managing the categories * - * @param {WPBlockCategory[]} state Current state. - * @param {Object} action Dispatched action. + * @param {BlockCategory[]} state Current state. + * @param {Object} action Dispatched action. * - * @return {WPBlockCategory[]} Updated state. + * @return {BlockCategory[]} Updated state. */ export function categories( state = DEFAULT_CATEGORIES, action ) { switch ( action.type ) { @@ -367,6 +378,13 @@ export function categories( state = DEFAULT_CATEGORIES, action ) { return state; } +/** + * Reducer managing the collections. + * + * @param {BlockStoreState} state The current state. + * @param {Object} action Dispatched action. + * @return {BlockStoreState} Updated state. + */ export function collections( state = {}, action ) { switch ( action.type ) { case 'ADD_BLOCK_COLLECTION': diff --git a/packages/blocks/src/store/selectors.js b/packages/blocks/src/store/selectors.js index b2b8ab8106f09..efac8a16b801e 100644 --- a/packages/blocks/src/store/selectors.js +++ b/packages/blocks/src/store/selectors.js @@ -14,18 +14,28 @@ import { pipe } from '@wordpress/compose'; */ import { getValueFromObjectPath } from './utils'; -/** @typedef {import('../api/registration').WPBlockVariation} WPBlockVariation */ -/** @typedef {import('../api/registration').WPBlockVariationScope} WPBlockVariationScope */ -/** @typedef {import('./reducer').WPBlockCategory} WPBlockCategory */ +/** + * @typedef {import('../types').BlockAttribute} BlockAttribute + * @typedef {import('../types').BlockAttributes} BlockAttributes + * @typedef {import('../types').BlockCategory} BlockCategory + * @typedef {import('../types').BlockCollection} BlockCollection + * @typedef {import('../types').BlockVariation} BlockVariation + * @typedef {import('../types').BlockVariationScope} BlockVariationScope + * @typedef {import('../types').BlockStyle} BlockStyle + * @typedef {import('../types').BlockSupports} BlockSupports + * @typedef {import('../types').BlockType} BlockType + * @typedef {import('../types').InnerBlockTemplate} InnerBlockTemplate + * @typedef {import('./types').BlockStoreState} BlockStoreState + */ /** * Given a block name or block type object, returns the corresponding * normalized block type object. * - * @param {Object} state Blocks state. - * @param {(string|Object)} nameOrType Block name or type object + * @param {BlockStoreState} state Blocks state. + * @param {string|BlockType} nameOrType Block name or type object * - * @return {Object} Block type object. + * @return {BlockType|undefined} Block type object. */ const getNormalizedBlockType = ( state, nameOrType ) => 'string' === typeof nameOrType @@ -35,7 +45,7 @@ const getNormalizedBlockType = ( state, nameOrType ) => /** * Returns all the available block types. * - * @param {Object} state Data state. + * @param {BlockStoreState} state Data state. * * @example * ```js @@ -58,7 +68,7 @@ const getNormalizedBlockType = ( state, nameOrType ) => * }; * ``` * - * @return {Array} Block Types. + * @return {BlockType[]} Block Types. */ export const getBlockTypes = createSelector( ( state ) => Object.values( state.blockTypes ), @@ -68,8 +78,8 @@ export const getBlockTypes = createSelector( /** * Returns a block type by name. * - * @param {Object} state Data state. - * @param {string} name Block type name. + * @param {BlockStoreState} state Data state. + * @param {string} name Block type name. * * @example * ```js @@ -100,7 +110,7 @@ export const getBlockTypes = createSelector( * }; * ``` * - * @return {Object?} Block Type. + * @return {BlockType|undefined} Block Type. */ export function getBlockType( state, name ) { return state.blockTypes[ name ]; @@ -109,8 +119,8 @@ export function getBlockType( state, name ) { /** * Returns block styles by block name. * - * @param {Object} state Data state. - * @param {string} name Block type name. + * @param {BlockStoreState} state Data state. + * @param {string} name Block type name. * * @example * ```js @@ -134,7 +144,7 @@ export function getBlockType( state, name ) { * }; * ``` * - * @return {Array?} Block Styles. + * @return {BlockStyle[]|undefined} Block Styles. */ export function getBlockStyles( state, name ) { return state.blockStyles[ name ]; @@ -143,9 +153,9 @@ export function getBlockStyles( state, name ) { /** * Returns block variations by block name. * - * @param {Object} state Data state. - * @param {string} blockName Block type name. - * @param {WPBlockVariationScope} [scope] Block variation scope name. + * @param {BlockStoreState} state Data state. + * @param {string} blockName Block type name. + * @param {BlockVariationScope=} scope Block variation scope name. * * @example * ```js @@ -169,7 +179,7 @@ export function getBlockStyles( state, name ) { * }; * ``` * - * @return {(WPBlockVariation[]|void)} Block variations. + * @return {(BlockVariation[]|undefined) & EnhancedSelector} Block variations. */ export const getBlockVariations = createSelector( ( state, blockName, scope ) => { @@ -200,10 +210,10 @@ export const getBlockVariations = createSelector( * and the variation's attributes and determines if a variation is active. * A function that accepts a block's attributes and the variation's attributes and determines if a variation is active. * - * @param {Object} state Data state. - * @param {string} blockName Name of block (example: “core/columns”). - * @param {Object} attributes Block attributes used to determine active variation. - * @param {WPBlockVariationScope} [scope] Block variation scope name. + * @param {BlockStoreState} state Data state. + * @param {string} blockName Name of block (example: “core/columns”). + * @param {BlockAttributes} attributes Block attributes used to determine active variation. + * @param {BlockVariationScope=} scope Block variation scope name. * * @example * ```js @@ -233,7 +243,7 @@ export const getBlockVariations = createSelector( * }; * ``` * - * @return {(WPBlockVariation|undefined)} Active block variation. + * @return {BlockVariation|undefined} Active block variation. */ export function getActiveBlockVariation( state, blockName, attributes, scope ) { const variations = getBlockVariations( state, blockName, scope ); @@ -267,9 +277,9 @@ export function getActiveBlockVariation( state, blockName, attributes, scope ) { * the last added item is picked. This simplifies registering overrides. * When there is no default variation set, it returns the first item. * - * @param {Object} state Data state. - * @param {string} blockName Block type name. - * @param {WPBlockVariationScope} [scope] Block variation scope name. + * @param {BlockStoreState} state Data state. + * @param {string} blockName Block type name. + * @param {BlockVariationScope=} scope Block variation scope name. * * @example * ```js @@ -296,7 +306,7 @@ export function getActiveBlockVariation( state, blockName, attributes, scope ) { * }; * ``` * - * @return {?WPBlockVariation} The default block variation. + * @return {BlockVariation|undefined} The default block variation. */ export function getDefaultBlockVariation( state, blockName, scope ) { const variations = getBlockVariations( state, blockName, scope ); @@ -311,7 +321,7 @@ export function getDefaultBlockVariation( state, blockName, scope ) { /** * Returns all the available block categories. * - * @param {Object} state Data state. + * @param {BlockStoreState} state Data state. * * @example * ```js @@ -334,7 +344,7 @@ export function getDefaultBlockVariation( state, blockName, scope ) { * }; * ``` * - * @return {WPBlockCategory[]} Categories list. + * @return {BlockCategory[]} Categories list. */ export function getCategories( state ) { return state.categories; @@ -343,7 +353,7 @@ export function getCategories( state ) { /** * Returns all the available collections. * - * @param {Object} state Data state. + * @param {BlockStoreState} state Data state. * * @example * ```js @@ -367,7 +377,7 @@ export function getCategories( state ) { * }; * ``` * - * @return {Object} Collections list. + * @return {BlockCollection[]} Collections list. */ export function getCollections( state ) { return state.collections; @@ -376,7 +386,7 @@ export function getCollections( state ) { /** * Returns the name of the default block name. * - * @param {Object} state Data state. + * @param {BlockStoreState} state Data state. * * @example * ```js @@ -400,7 +410,7 @@ export function getCollections( state ) { * }; * ``` * - * @return {string?} Default block name. + * @return {string|undefined} Default block name. */ export function getDefaultBlockName( state ) { return state.defaultBlockName; @@ -409,7 +419,7 @@ export function getDefaultBlockName( state ) { /** * Returns the name of the block for handling non-block content. * - * @param {Object} state Data state. + * @param {BlockStoreState} state Data state. * * @example * ```js @@ -436,7 +446,7 @@ export function getDefaultBlockName( state ) { * }; * ``` * - * @return {string?} Name of the block for handling non-block content. + * @return {string|undefined} Name of the block for handling non-block content. */ export function getFreeformFallbackBlockName( state ) { return state.freeformFallbackBlockName; @@ -445,7 +455,7 @@ export function getFreeformFallbackBlockName( state ) { /** * Returns the name of the block for handling unregistered blocks. * - * @param {Object} state Data state. + * @param {BlockStoreState} state Data state. * * @example * ```js @@ -472,7 +482,7 @@ export function getFreeformFallbackBlockName( state ) { * }; * ``` * - * @return {string?} Name of the block for handling unregistered blocks. + * @return {string|undefined} Name of the block for handling unregistered blocks. */ export function getUnregisteredFallbackBlockName( state ) { return state.unregisteredFallbackBlockName; @@ -481,7 +491,7 @@ export function getUnregisteredFallbackBlockName( state ) { /** * Returns the name of the block for handling the grouping of blocks. * - * @param {Object} state Data state. + * @param {BlockStoreState} state Data state. * * @example * ```js @@ -508,7 +518,7 @@ export function getUnregisteredFallbackBlockName( state ) { * }; * ``` * - * @return {string?} Name of the block for handling the grouping of blocks. + * @return {string|undefined} Name of the block for handling the grouping of blocks. */ export function getGroupingBlockName( state ) { return state.groupingBlockName; @@ -517,8 +527,8 @@ export function getGroupingBlockName( state ) { /** * Returns an array with the child blocks of a given block. * - * @param {Object} state Data state. - * @param {string} blockName Block type name. + * @param {BlockStoreState} state Data state. + * @param {string} blockName Block type name. * * @example * ```js @@ -542,7 +552,7 @@ export function getGroupingBlockName( state ) { * }; * ``` * - * @return {Array} Array of child block names. + * @return {string[]} Array of child block names. */ export const getChildBlockNames = createSelector( ( state, blockName ) => { @@ -558,11 +568,11 @@ export const getChildBlockNames = createSelector( /** * Returns the block support value for a feature, if defined. * - * @param {Object} state Data state. - * @param {(string|Object)} nameOrType Block name or type object - * @param {Array|string} feature Feature to retrieve - * @param {*} defaultSupports Default value to return if not - * explicitly defined + * @param {BlockStoreState} state Data state. + * @param {string|BlockType} nameOrType Block name or type object + * @param {string|string[]} feature Feature to retrieve + * @param {*} defaultSupports Default value to return if not + * explicitly defined * * @example * ```js @@ -587,7 +597,7 @@ export const getChildBlockNames = createSelector( * }; * ``` * - * @return {?*} Block support value + * @return {*} Block support value */ export const getBlockSupport = ( state, @@ -610,11 +620,12 @@ export const getBlockSupport = ( /** * Returns true if the block defines support for a feature, or false otherwise. * - * @param {Object} state Data state. - * @param {(string|Object)} nameOrType Block name or type object. - * @param {string} feature Feature to test. - * @param {boolean} defaultSupports Whether feature is supported by - * default if not explicitly defined. + * @param {BlockStoreState} state Data state. + * @param {string|BlockType} nameOrType Block name or type object. + * @param {string} feature Feature to test. + * + * @param {boolean} defaultSupports Whether feature is supported by + * default if not explicitly defined. * * @example * ```js @@ -649,9 +660,9 @@ export function hasBlockSupport( state, nameOrType, feature, defaultSupports ) { * Returns true if the block type by the given name or object value matches a * search term, or false otherwise. * - * @param {Object} state Blocks state. - * @param {(string|Object)} nameOrType Block name or type object. - * @param {string} searchTerm Search term by which to filter. + * @param {BlockStoreState} state Blocks state. + * @param {string|BlockType} nameOrType Block name or type object. + * @param {string} searchTerm Search term by which to filter. * * @example * ```js @@ -682,7 +693,7 @@ export function hasBlockSupport( state, nameOrType, feature, defaultSupports ) { * }; * ``` * - * @return {Object[]} Whether block type matches search term. + * @return {boolean} Whether block type matches search term. */ export function isMatchingSearchTerm( state, nameOrType, searchTerm ) { const blockType = getNormalizedBlockType( state, nameOrType ); @@ -721,8 +732,8 @@ export function isMatchingSearchTerm( state, nameOrType, searchTerm ) { /** * Returns a boolean indicating if a block has child blocks or not. * - * @param {Object} state Data state. - * @param {string} blockName Block type name. + * @param {BlockStoreState} state Data state. + * @param {string} blockName Block type name. * * @example * ```js @@ -756,8 +767,8 @@ export const hasChildBlocks = ( state, blockName ) => { /** * Returns a boolean indicating if a block has at least one child block with inserter support. * - * @param {Object} state Data state. - * @param {string} blockName Block type name. + * @param {BlockStoreState} state Data state. + * @param {string} blockName Block type name. * * @example * ```js diff --git a/packages/blocks/src/store/types.ts b/packages/blocks/src/store/types.ts new file mode 100644 index 0000000000000..8311b7dc9e9d6 --- /dev/null +++ b/packages/blocks/src/store/types.ts @@ -0,0 +1,67 @@ +/** + * Internal dependencies + */ +import type { + BlockCategory, + BlockCollection, + BlockVariation, + BlockStyle, + BlockType, +} from '../types'; + +/** + * The state of the `core/blocks` redux store. + * + * @public + */ +export type BlockStoreState = { + /** + * Block variations by block name. + */ + blockVariations: Record< string, BlockVariation[] >; + + /** + * Block styles by block name. + */ + blockStyles: Record< string, BlockStyle[] >; + + /** + * Block type by name. + */ + blockTypes: Record< string, BlockType< any > >; + + /** + * The available block categories. + */ + categories: BlockCategory[]; + + /** + * The available collections. + */ + collections: BlockCollection[]; + + /** + * Name of the default block name. + */ + defaultBlockName?: string; + + /** + * Name of the block for handling non-block content. + */ + freeformFallbackBlockName?: string; + + /** + * Name of the block for handling unregistered blocks. + */ + unregisteredFallbackBlockName?: string; + + /** + * Name of the block for handling the grouping of blocks. + */ + groupingBlockName?: string; + + /** + * Unprocessed block types. + */ + unprocessedBlockTypes?: any[]; +}; diff --git a/packages/blocks/src/types/block-attributes.ts b/packages/blocks/src/types/block-attributes.ts new file mode 100644 index 0000000000000..a1265eca40ef1 --- /dev/null +++ b/packages/blocks/src/types/block-attributes.ts @@ -0,0 +1,312 @@ +/** + * Block Attribute Interfaces + * + * @module BlockAttributes + */ + +/** + * External dependencies + */ +import type { ReactChild } from 'react'; + +/** + * Types of data stored by block attributes. + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-attributes/#type-validation Type Validation} on developer.wordpress.org + */ +export type AttributeSchemaType = + | 'string' + | 'boolean' + | 'object' + | 'null' + | 'array' + | 'integer' + | 'number'; + +export type BaseAttributeSource = { + type: AttributeSchemaType | AttributeSchemaType[]; +}; + +/** + * Used in [get-block-attributes.js](../api/parser/get-block-attributes.js) + * + * - [ ] TODO this isn't defined in {@link https://github.com/WordPress/gutenberg/blob/trunk/schemas/json/block.json block.json} + * - [ ] TODO is this only used internally? + * + * @internal + */ +export interface Raw { + source: 'raw'; + type: 'string'; // TODO is this correct? +} + +/** + * Attribute sourced from an attribute of a tag in the markup. + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-attributes/#attribute-source Attribute Source} on developer.wordpress.org + * @public + */ +export type Attribute = { + source: 'attribute'; + attribute: string; + selector?: string; +} & ( + | { + type: 'boolean'; + default?: boolean; + } + | { + type: 'number'; + default?: number; + } + | { + type: 'string'; + default?: string; + } +); + +/** + * Used in [get-block-attributes.js](../api/parser/get-block-attributes.js) + * + * - [ ] TODO this isn't defined in {@link https://github.com/WordPress/gutenberg/blob/trunk/schemas/json/block.json block.json} + * - [ ] TODO is this only used internally? + * + * @internal + */ +export interface Property { + source: 'property'; + type: 'string'; // TODO is this correct? +} + +/** + * @internal + */ +export interface Children { + source: 'children'; + type: 'array'; + selector?: string; +} + +/** + * Used in [get-block-attributes.js](../api/parser/get-block-attributes.js) + * + * - [ ] TODO this isn't defined in {@link https://github.com/WordPress/gutenberg/blob/trunk/schemas/json/block.json block.json} + * - [ ] TODO is this only used internally? + * + * @internal + */ +export interface Node { + source: 'node'; + type: 'string'; // TODO is this correct? + selector?: string; +} + +/** + * Used in [get-block-attributes.js](../api/parser/get-block-attributes.js) + * + * - [ ] TODO this isn't defined in {@link https://github.com/WordPress/gutenberg/blob/trunk/schemas/json/block.json block.json} + * - [ ] TODO is this only used internally? + * + * @internal + */ +export interface Tag { + source: 'tag'; + type: 'string'; // TODO is this correct? + selector?: string; +} + +/** + * Attribute sourced from the inner HTML from markup. + * + * Typically used by RichText. Note that text is returned according to the rules of {@link https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML innerHTML} on developer.wordpress.org + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-attributes/#html-source HTML Source} on developer.wordpress.org + * @public + */ +export interface HTML { + source: 'html'; + type: 'string'; + multiline?: 'li' | 'p'; + selector?: string; + default?: string; +} + +/** + * Attribute sourced from a post’s meta. + * + * {@link https://github.com/WordPress/gutenberg/blob/c367c4e2765f9e6b890d1565db770147efca5d66/packages/core-data/src/entity-provider.js EntityProvider and related hook APIs} should be used instead. + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-attributes/#meta-source-deprecated Meta Source} on developer.wordpress.org + * @deprecated + * @public + */ +export interface Meta { + source: 'meta'; + type: 'string'; + meta: string; + default?: string; +} + +/** + * Attribute sourced from array of values from markup. + * + * Entries of the array are determined by the selector argument, where each matched element within + * the block will have an entry structured corresponding to the second argument, an object of + * attribute sources. + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-attributes/#query-source Query Source} on developer.wordpress.org + * @public + */ +export interface Query< T > { + source: 'query'; + type: 'array'; + selector: string; + query: { + [ k in keyof T ]: BlockAttribute< + T[ k ] extends Array< infer U > ? U : T[ k ] + >; + }; + default?: any[]; +} + +/** + * Use text to extract the inner text from markup. + * + * Note that HTML is returned according to the rules of {@link https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent textContent }. + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-attributes/#text-source Text Source} on developer.wordpress.org + * @public + */ +export interface Text { + source: 'text'; + type: 'string'; + selector?: string; + default?: string; +} + +/** + * @internal + */ +export type None = { + source?: never; +} & ( + | { + type: 'array'; + default?: any[]; + } + | { + type: 'object'; + default?: object; + } + | { + type: 'boolean'; + default?: boolean; + } + | { + type: 'number'; + default?: number; + } + | { + type: 'string'; + default?: string; + } +); + +/** + * @internal + */ +export type Primitive = 'array' | 'object' | 'boolean' | 'number' | 'string'; + +/** + * Union of block attribute schemas. + * + * @public + */ +export type BlockAttributeSchema< T > = ( + | Raw + | Attribute + | Property + | Children + | Node + | Tag + | HTML + | Meta + | Query< T > + | Text + | None +) & { + /** + * Role of the block. + * + * Used in [selectors.js](../store/selectors.js) and [utils.js](../api/utils.js) + * + * @internal + */ + __experimentalRole?: string; +}; + +/** + * @public + */ +export type BlockAttribute< T > = BlockAttributeSchema< T > | Primitive; + +/** + * Attributes definition providing information about the data stored by a block. + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-attributes/ Attributes} + * @public + */ +export type BlockAttributes< T extends Record< string, any > = {} > = Record< + string, + BlockAttribute< T > +> & { + /** + * Provide an additional `className`, which used to be supported in the `core/comments-query-loop` block. + * + * Used in [convert-legacy-block.js](../api/parser/convert-legacy-block.js) and + * [fix-custom-classname.js](../api/parser/fix-custom-classname.js) + * + * @deprecated This is a legacy property and should not be used. + */ + className?: string; + + /** + * Used in [convert-legacy-block.js](../api/parser/convert-legacy-block.js) + * + * @deprecated This is a legacy property and should not be used. + */ + legacy?: boolean; + + /** + * Used in [convert-legacy-block.js](../api/parser/convert-legacy-block.js) + * + * @deprecated This is a legacy property and should not be used. + */ + responsive?: boolean; + + /** + * Used in [convert-legacy-block.js](../api/parser/convert-legacy-block.js) + * + * @deprecated This is a legacy property and should not be used. + */ + service?: string; +}; + +/** + * Return type of [`parseWithAttributeSchema`](../api/parser/get-block-attributes.js). + */ +export type SourceReturnValue< T > = T extends Attribute & { type: 'boolean' } + ? boolean | undefined + : T extends Children + ? ReactChild[] + : T extends Node + ? Element | null + : T extends Tag + ? keyof ( HTMLElementTagNameMap & SVGElementTagNameMap ) | undefined + : T extends Query< infer U > + ? { + [ k in keyof U ]: U[ k ] extends Query< infer V > + ? SourceReturnValue< Query< V > > + : SourceReturnValue< U[ k ] >; + } + : string | undefined; diff --git a/packages/blocks/src/types/block-category.ts b/packages/blocks/src/types/block-category.ts new file mode 100644 index 0000000000000..ca54f8fb636de --- /dev/null +++ b/packages/blocks/src/types/block-category.ts @@ -0,0 +1,35 @@ +/** + * Block Category Interface + * + * @module BlockCategory + */ + +/** + * Internal dependencies + */ +import type { BlockType } from './block-type'; +import type { BlockIconRenderer } from './block-icon'; + +/** + * Custom category of {@link BlockType}. + * + * Note, similar in concept but differs from {@link BlockType.category} which are core categories. + * + * @public + */ +export interface BlockCategory { + /** + * Unique category slug. + */ + slug: string; + + /** + * Category label, for display in user interface. + */ + title: string; + + /** + * Optional icon, for display in user interface. + */ + icon?: BlockIconRenderer; +} diff --git a/packages/blocks/src/types/block-collection.ts b/packages/blocks/src/types/block-collection.ts new file mode 100644 index 0000000000000..cddf34bd227de --- /dev/null +++ b/packages/blocks/src/types/block-collection.ts @@ -0,0 +1,16 @@ +/** + * Internal dependencies + */ +import type { BlockIconRenderer } from './block-icon'; +import type { BlockStoreState } from '../store/types'; + +/** + * Describes a block collection. + * + * @see {@link BlockStoreState.collections} + * @public + */ +export interface BlockCollection { + title: string; + icon?: BlockIconRenderer; +} diff --git a/packages/blocks/src/types/block-depreciation.ts b/packages/blocks/src/types/block-depreciation.ts new file mode 100644 index 0000000000000..be93ebac4f7f7 --- /dev/null +++ b/packages/blocks/src/types/block-depreciation.ts @@ -0,0 +1,42 @@ +/** + * Internal dependencies + */ +import type { Block } from './block'; +import type { BlockType } from './block-type'; + +/** + * {@link BlockType} depreciation handler. + * + * Defines migration of deprecated blocks to the current version. + * + * @see {@link BlockType.deprecated} + * @public + */ +export interface BlockDeprecation< + // The new block attribute types. + NewAttributes extends Record< string, any > = {}, + // The old block attribute types. + OldAttributes extends Record< string, any > = {}, +> extends Pick< + BlockType< OldAttributes >, + 'attributes' | 'save' | 'supports' + > { + /** + * A function which, given the attributes and inner blocks of the + * parsed block, returns true if the deprecation can handle the block + * migration. This is particularly useful in cases where a block is + * technically valid even once deprecated, and requires updates to its + * attributes or inner blocks. + */ + isEligible?( attributes: OldAttributes, innerBlocks: Block[] ): boolean; + + /** + * A function which, given the old attributes and inner blocks is + * expected to return either the new attributes or a tuple array of + * [attributes, innerBlocks] compatible with the block. + */ + migrate?( + attributes: OldAttributes, + innerBlocks: Block[] + ): NewAttributes | [ NewAttributes, Block[] ]; +} diff --git a/packages/blocks/src/types/block-icon.ts b/packages/blocks/src/types/block-icon.ts new file mode 100644 index 0000000000000..8934418b1e017 --- /dev/null +++ b/packages/blocks/src/types/block-icon.ts @@ -0,0 +1,61 @@ +/** + * Block Icon Interfaces + * + * @module BlockIcon + */ + +/** + * External dependencies + */ +import type { ComponentType } from 'react'; + +/** + * Internal dependencies + */ +import type { BlockType } from './block-type'; + +/** + * An icon type definition. One of a Dashicon slug, an element, + * or a component. + * + * @see {@link https://developer.wordpress.org/resource/dashicons/ Dashicons} on developer.wordpress.org + * @public + */ +export type BlockIconRenderer< T = {} > = string | Element | ComponentType< T >; + +/** + * Describes a normalized block type icon. + * + * @see {@link BlockType.icon} + * @public + */ +export interface BlockIconNormalized { + /** + * Render behavior of the icon, one of a Dashicon slug, an element, or a component. + */ + src: BlockIconRenderer; + + /** + * Optimal background hex string color when displaying icon. + */ + background?: string; + + /** + * Optimal foreground hex string color when displaying icon. + */ + foreground?: string; + + /** + * Optimal shadow hex string color when displaying icon. + */ + shadowColor?: string; +} + +/** + * Type for rendering the icon of a {@link BlockType} in an editor interface, + * either a Dashicon slug, an element, a component, or an object describing + * the icon. + * + * @public + */ +export type BlockIcon = BlockIconRenderer | BlockIconNormalized; diff --git a/packages/blocks/src/types/block-node.ts b/packages/blocks/src/types/block-node.ts new file mode 100644 index 0000000000000..d5b4e38c31ff4 --- /dev/null +++ b/packages/blocks/src/types/block-node.ts @@ -0,0 +1,53 @@ +/** + * Block Node Interface + * + * @module BlockNode + */ + +/** + * The "block node" represents a transition from serialized block data + * into a fully-loaded block with its implementation. It contains the + * information parsed from the input document; be that serialized HTML + * as is the default case in WordPress, or directly loaded from a + * structured data store. + * + * Block nodes do not indicate all of a block's attributes, as some of + * its attributes may be sourced later on from the `innerHTML` by the + * block implementation. This is one example of where the block node + * is not a complete "block" and requires further processing. + * + * Block validation only examines `innerHTML` and delegates the validation + * of any inner blocks to the block loading process for those blocks. + * This prevents an issue with a potentially deeply-nested inner block + * from cascading up and invalidating all of its parent blocks. + * + * @public + */ +export type BlockNode = { + /** + * Name indicating namespaced block type, e.g. for example, "myplugin/my-interesting-block". + * A `null` block name is given to a section of freeform HTML content. + */ + blockName?: string; + + /** + * Attributes sourced from parsed JSON in the block comment delimiters. + * When unable to parse block comment attributes, `attrs` will be `null`. + */ + attrs?: Record< string, any >; + + /** + * Full text inside block boundaries excluding inner block content. + */ + innerHTML: string; + + /** + * Indicates arrangement of text chunks and inner blocks. + */ + innerContent: Array< string | null >; + + /** + * Nested block nodes; may be empty. + */ + innerBlocks: BlockNode[]; +}; diff --git a/packages/blocks/src/types/block-props.ts b/packages/blocks/src/types/block-props.ts new file mode 100644 index 0000000000000..59af104c756c3 --- /dev/null +++ b/packages/blocks/src/types/block-props.ts @@ -0,0 +1,29 @@ +/** + * Internal dependencies + */ +import type { BlockType } from './block-type'; + +/** + * Describes the `save` component props of a {@link BlockType}. + * + * @see {@link BlockType.save} + * @public + */ +export interface BlockSaveProps< Attributes extends Record< string, any > > { + className: string; + attributes: Attributes; +} + +/** + * Describes the `edit` component props of a {@link BlockType}. + * + * @see {@link BlockType.edit} + * @public + */ +export interface BlockEditProps< Attributes extends Record< string, any > > + extends BlockSaveProps< Attributes > { + clientId: string; + isSelected: boolean; + setAttributes: ( attrs: Partial< Attributes > ) => void; + context: Record< string, any >; +} diff --git a/packages/blocks/src/types/block-supports.ts b/packages/blocks/src/types/block-supports.ts new file mode 100644 index 0000000000000..9268acfd35158 --- /dev/null +++ b/packages/blocks/src/types/block-supports.ts @@ -0,0 +1,375 @@ +/** + * Internal dependencies + */ +import type { BlockType } from './block-type'; + +/** + * Control type used to indicate axial (column/row) block spacing controls. + * + * @see {@link BlockSupports.spacing} + * @public + */ +export type AxialDirection = 'horizontal' | 'vertical'; + +/** + * Control type used to indicate CSS spacing for arbitrary sides. + * + * @see {@link BlockSupports.spacing} + * @public + */ +export type CSSDirection = 'top' | 'right' | 'bottom' | 'left'; + +/** + * Control type used to indicate block’s alignment. + * + * @see {@link BlockSupports.align} + * @public + */ +export type BlockAlignment = 'left' | 'center' | 'right' | 'wide' | 'full'; + +/** + * CSS style properties related to dimensions of {@link BlockSupports}. + * + * When it does, the block editor will show UI controls for the user to set their values if + * {@link https://developer.wordpress.org/block-editor/how-to-guides/themes/theme-json/#opt-in-into-ui-controls the theme declares support}. + * + * @see {@link BlockSupports.dimensions} + * @public + */ +export type BlockDimensions = { + /** + * Enable min height control. + */ + minHeight: boolean; +}; + +/** + * {@link BlockSupports} interface to enable CSS style properties related to position. + * + * When it does, the block editor will show UI controls for the user to set their values if + * {@link https://developer.wordpress.org/block-editor/how-to-guides/themes/theme-json/#opt-in-into-ui-controls the theme declares support}. + * + * @see {@link BlockSupports.position} + * @public + */ +export type BlockPosition = { + /** + * Enable selecting sticky position. + */ + sticky: boolean; +}; + +/** + * {@link BlockSupports} interface to enable some of the properties related to color. + * + * Enables UI color controls in the block editor. + * + * @see {@link BlockSupports.color} + * @public + */ +export interface ColorProps { + /** + * This property adds UI controls which allow the user to apply + * a solid background color to a block. + * + * When the block declares support for `color.background`, + * the attributes of a block will include two new entries: + * `backgroundColor` and `style`. + * + * (default) true + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-supports/#color-background https://developer.wordpress.org} + */ + background: boolean; + + /** + * This property adds UI controls which allow the user to apply + * a gradient background to a block. + * + * When the block declares support for `color.background`, + * the attributes of a block will include two new entries: + * `gradient` and `style`. + * + * (default) false + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-supports/#color-gradients color.gradients} on developer.wordpress.org + */ + gradients: boolean; + + /** + * This property adds block controls which allow the user + * to set link color in a block, link color is disabled by default. + * + * (default) false + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-supports/#color-link color.link} on developer.wordpress.org + */ + link: boolean; + + /** + * This property adds block controls which allow the user + * to set text color in a block. + * + * (default) true + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-supports/#color-text color.text} on developer.wordpress.org + */ + text: boolean; + + /** + * This property adds UI controls which allow to apply a duotone filter + * to a block or part of a block. + * + * (default) undefined + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-supports/#color-__experimentalduotone __experimentalDuotone} on developer.wordpress.org + * @internal + */ + __experimentalDuotone?: string; +} + +/** + * {@link BlockSupports} interface to enable some typography related properties. + * + * When it does, the block editor will show a typography UI allowing the user to control their values. + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-supports/#typography typography} on developer.wordpress.org + * @public + */ + +export interface TypographyProps { + /** + * This value signals that a block supports the font-size + * CSS style property. When it does, the block editor will + * show an UI control for the user to set its value. + * + * The values shown in this control are the ones declared + * by the theme via the editor-font-sizes theme support, + * or the default ones if none are provided. + * + * (default) false + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-supports/#typography-fontsize fontSize} on developer.wordpress.org + * @see {@link https://developer.wordpress.org/block-editor/how-to-guides/themes/theme-support/#block-font-sizes Font Size} on developer.wordpress.org + */ + fontSize: boolean; + + /** + * This value signals that a block supports the line-height + * CSS style property. When it does, the block editor will + * show an UI control for the user to set its value if the + * theme declares support. + * + * (default) false + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-supports/#typography-lineheight lineHeight} on developer.wordpress.org + * @see {@link https://developer.wordpress.org/block-editor/how-to-guides/themes/theme-support/#supporting-custom-line-heights Line Heights} on developer.wordpress.org + */ + lineHeight: boolean; +} + +/** + * {@link BlockSupports} interface to enable some of the CSS style properties related to spacing. + * + * When it does, the block editor will show UI controls for the user to set their values if + * {@link https://developer.wordpress.org/block-editor/how-to-guides/themes/theme-json/#opt-in-into-ui-controls the theme declares support}. + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-supports/#spacing spacing} on developer.wordpress.org + * @public + */ +export interface SpacingProps { + blockGap: boolean | AxialDirection[]; + /** + * Enable margin control UI for all or specified element directions + * + * (default) false + */ + margin: boolean | CSSDirection[]; + + /** + * Enable padding control UI for all or specified element directions + * + * (default) false + */ + padding: boolean | CSSDirection[]; + + /** + * Whether to skip the serialization to HTML markup. + * Provide `true` to skip serialization for all block supports. + * Alternatively, provide an array of block supports for which skip + * serialization to HTML markup. + * + * Used in [private-selectors.js]()./store/private-selectors.js) + * + * @internal + */ + __experimentalSkipSerialization?: true | string[]; +} + +/** + * Interface to allow alternative styles to be applied to existing blocks. + * + * Works by adding a className to the block’s wrapper. This className can be used to provide + * an alternative styling for the block if the block style is selected. + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-styles/ Styles} on developer.wordpress.org + * @public + */ +export interface BlockStyle { + name: string; + label: string; + isDefault?: boolean; +} + +/** + * Description of {@link BlockType} support for editor features. + * + * @see {@link BlockType.supports} + * @public + */ +export interface BlockSupports { + /** + * This property adds block controls which allow to change block's + * alignment. + * + * (default) false + */ + align?: boolean | BlockAlignment[]; + + /** + * Enable wide alignment (depends on `align`). + * + * (default) true + */ + alignWide?: boolean; + + /** + * Anchors let you link directly to a specific block on a page. This + * property adds a field to define an id for the block and a button to + * copy the direct link. + * + * (default) false + */ + anchor?: boolean; + + /** + * This value signals that a block supports some of the properties + * related to color. When it does, the block editor will show + * UI controls for the user to set their values. + * + * NOTE: The `background` and `text` keys have a default value + * of `true`, so if the color property is present they’ll also + * be considered enabled. + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-supports/#color BlockSupports.color} on developer.wordpress.org + */ + color?: Partial< ColorProps >; + + /** + * This property adds a field to define a custom className for the + * block's wrapper. + * + * (default) true + */ + customClassName?: boolean; + + /** + * By default, Gutenberg adds a class with the form + * `.wp-block-your-block-name` to the root element of your saved + * markup. + * + * (default) true + */ + className?: boolean; + + /** + * By default, Gutenberg will allow a block's markup to be edited + * individually. To disable this behavior, set `html` to `false` + * + * (default) true + */ + html?: boolean; + + /** + * By default, all blocks will appear in the Gutenberg inserter. To + * hide a block so that it can only be inserted programmatically, set + * to false + * + * (default) true + */ + inserter?: boolean; + + /** + * A non-multiple block can be inserted into each post, one time only. + * + * (default) true + */ + multiple?: boolean; + + /** + * By default all blocks can be converted to a reusable block. + * + * (default) true + */ + reusable?: boolean; + + /** + * This value signals that a block supports some of the CSS style + * properties related to spacing. + * + * When the block declares support for a specific spacing property, + * the attributes definition is extended to include the `style` attribute. + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-supports/#spacing BlockSupports.spacing} on developer.wordpress.org + */ + spacing?: Partial< SpacingProps >; + + /** + * A block may want to disable the ability to toggle the lock state. + * It can be locked/unlocked by a user from the block “Options” + * dropdown by default. To disable this behavior, set `lock` to `false`. + * + * (default) true + */ + lock?: boolean; + + /** + * A block may want to disable the ability to toggle the lock state. + * It can be locked/unlocked by a user from the block “Options” + * dropdown by default. To disable this behavior, set `lock` to `false`. + */ + typography?: Partial< TypographyProps >; + + /** + * This value signals that a block supports some of the CSS style properties related to shadow. + * + * Used in [private-selector.js](./store/private-selector.js) + */ + shadow: any; + + /** + * This value signals that a block supports some of the CSS style properties related to + * dimensions. + * + * (default) null + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-supports/#dimensions BlockSupports.dimensions} on developer.wordpress.org + */ + dimensions: BlockDimensions; + + /** + * This value signals that a block supports some of the CSS style properties related to position. + * + * (default) null + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-supports/#position BlockSupports.position} on developer.wordpress.org + */ + position: BlockPosition; + + /** + * CSS selector to use instead of the default `.wp-block-` selector. + * + * @internal + */ + __experimentalSelector: any; +} diff --git a/packages/blocks/src/types/block-type.ts b/packages/blocks/src/types/block-type.ts new file mode 100644 index 0000000000000..f77059026415b --- /dev/null +++ b/packages/blocks/src/types/block-type.ts @@ -0,0 +1,287 @@ +/** + * External dependencies + */ + +import type { ComponentType } from 'react'; + +/** + * Internal dependencies + */ +import type { BlockAttribute, BlockAttributes } from './block-attributes'; +import type { BlockCategory } from './block-category'; +import type { BlockDeprecation } from './block-depreciation'; +import type { BlockIcon, BlockIconNormalized } from './block-icon'; +import type { BlockEditProps, BlockSaveProps } from './block-props'; +import type { BlockStyle, BlockSupports } from './block-supports'; +import type { Transform } from './transform'; + +/** + * Core provided {@link BlockType} category type. + * + * Plugins and Themes can also register other custom {@link BlockCategory block categories}. + * + * @public + */ +export type BlockTypeCategory = + | 'text' + | 'media' + | 'design' + | 'widgets' + | 'theme' + | 'embed'; + +/** + * Internal type for the innerBlocks property inside of the example + * + * @see BlockType.example + * @see {@link https://github.com/DefinitelyTyped/DefinitelyTyped/pull/55245#discussion_r692208988} + * @internal + */ +export type BlockExampleInnerBlock = Partial< BlockType > & + Pick< BlockType, 'name' | 'attributes' > & { + innerBlocks?: BlockExampleInnerBlock[]; + }; + +/** + * Configuration of a {@link BlockType}. + * + * Used by `registerBlockType` in [registration.js](../api/registration.js) + * + * @public + */ +export type BlockConfiguration< + Attributes extends Record< string, any > = {}, +> = Partial< Omit< BlockType< Attributes >, 'icon' > > & + Pick< BlockType< Attributes >, 'attributes' | 'category' | 'title' > & { + icon?: BlockIcon; + }; + +/** + * Defined behavior of a block type. + * + * @memberof module:blocks/BlockType + * @public + */ +export interface BlockType< Attributes extends Record< string, any > = {} > { + /** + * The version of the Block API used by the block. + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/#api-version} + */ + apiVersion?: number; + + /** + * Attributes for the block. + */ + attributes: { + [ k in keyof Attributes ]: BlockAttribute< + Attributes[ k ] extends Array< infer U > ? U : Attributes[ k ] + >; + }; + + /** + * The block category (determines placement in the inserter). + */ + category: BlockTypeCategory; + + /** + * Array of deprecation handlers for the block. + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-deprecation/ Deprecation} + */ + deprecated?: BlockDeprecation< Attributes >[]; + + /** + * This is a short description for your block, which can be translated + * with our translation functions. + */ + description?: string; + + /** + * Component to render in the editor. + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-edit-save/#edit Edit and Save} on developer.wordpress.org + */ + edit?: ComponentType< BlockEditProps< Attributes > >; + + /** + * Block type editor script definition. + * It will only be enqueued in the context of the editor. + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/#editor-script} + */ + editorScript?: string; + + /** + * Block type editor style definition. + * It will only be enqueued in the context of the editor. + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/#editor-style} + */ + editorStyle?: string; + + /** + * It provides structured example data for the block. + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/#example} + */ + + example?: Partial< BlockType > & { + innerBlocks?: BlockExampleInnerBlock[]; + }; + + /** + * Icon for the block. + */ + icon: BlockIconNormalized; + + /** + * Searchable keywords for discovery. + */ + keywords?: string[]; + + /** + * Setting `parent` lets a block require that it is only available when + * nested within the specified blocks. + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/#parent} + */ + parent?: string[]; + + /** + * Setting `ancestor` lets a block require that it is only available when + * nested within the specified blocks. + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/#ancestor} + */ + ancestor?: string[]; + + /** + * Context provided for available access by descendants of blocks of this + * type, in the form of an object which maps a context name to one of the + * block’s own attribute. + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/#provides-context} + */ + providesContext?: Record< string, keyof Attributes >; + + /** + * This is set internally when registering the type. + */ + name: string; + + /** + * Component to render on the frontend. + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-edit-save/#edit Edit and Save} on developer.wordpress.org + */ + save: ComponentType< BlockSaveProps< Attributes > >; + + /** + * Block type frontend script definition. + * It will be enqueued both in the editor and when viewing the content on + * the front of the site. + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/#script} + */ + script?: string; + + /** + * Block type editor style definition. + * It will only be enqueued in the context of the editor. + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/#style} + */ + style?: string; + + /** + * Block styles. + * + * @see {@link https://wordpress.org/gutenberg/handbook/extensibility/extending-blocks/#block-style-variations} + */ + styles?: BlockStyle[]; + + /** + * Optional block extended support features. + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-supports/ Block Supports} on developer.wordpress.org + */ + supports?: BlockSupports; + + /** + * The gettext text domain of the plugin/block. + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/#text-domain} + */ + textdomain?: string; + + /** + * This is the display title for your block, which can be translated + * with our translation functions. + */ + title: string; + + /** + * Block transformations. + */ + transforms?: + | { + /** + * Transforms from another block type to this block type. + */ + from?: Transform< Attributes >[]; + /** + * Transforms from this block type to another block type. + */ + to?: Transform[]; + /** + * The transformations available for mobile devices. + * + * Used in [factory.js](../api/factory.js) + */ + supportedMobileTransforms?: string[]; + } + | undefined; + + /** + * Array of the names of context values to inherit from an ancestor + * provider. + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/#context} + */ + usesContext?: string[]; + + /** + * The current version number of the block, such as 1.0 or 1.0.3. + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/#version} + */ + version?: string; + + /** + * Sets attributes on the topmost parent element of the current block. + */ + getEditWrapperProps?( + attrs: Attributes + ): Record< string, string | number | boolean >; + + /** + * A function that defines how new attributes are merged with existing ones. + * + * Used in [paragraph](../../../block-library/src/paragraph/index.js) + */ + merge?( + attributes: Attributes, + attributesToMerge: Attributes + ): Partial< Attributes >; + + /** + * Custom block label callback function + * + * @internal + */ + __experimentalLabel( + attributes: BlockAttributes, + settings: { context: 'accessibility' | 'visual' } // TODO find all context types + ): string; +} diff --git a/packages/blocks/src/types/block-variation.ts b/packages/blocks/src/types/block-variation.ts new file mode 100644 index 0000000000000..a51c142762cfa --- /dev/null +++ b/packages/blocks/src/types/block-variation.ts @@ -0,0 +1,115 @@ +/** + * Internal dependencies + */ +import type { Block } from './block'; +import type { BlockAttributes } from './block-attributes'; +import type { BlockIcon } from './block-icon'; +import type { BlockExampleInnerBlock, BlockType } from './block-type'; +/** + * Type to scope where a variation is applicable. + * + * @public + */ +export type BlockVariationScope = 'block' | 'inserter' | 'transform'; + +/** + * TODO Undocumented + * + * @public + */ +export type InnerBlockTemplate = [ + string, + BlockAttributes?, + InnerBlockTemplate[]?, +]; + +/** + * Describes a related variations of a {@link BlockType}. + * + * Differentiated by setting some initial attributes or inner blocks. + * + * Used in [registration.js](../api/registration.js) + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-variations/ Block Variations} + * @public + */ +export interface BlockVariation< + Attributes extends BlockAttributes = BlockAttributes, +> { + /** + * The unique and machine-readable name. + */ + name: string; + + /** + * A human-readable variation title. + */ + title: string; + + /** + * A detailed variation description. + */ + description?: string; + + /** + * Block type category classification, used in search interfaces to arrange block types by category. + */ + category?: string; + + /** + * An icon helping to visualize the variation. + */ + icon?: BlockIcon; + + /** + * Indicates whether the current variation is the default one. Defaults to `false`. + */ + isDefault?: boolean; + + /** + * Values which override block attributes. + */ + attributes?: Attributes; + + /** + * Initial configuration of nested blocks. + */ + innerBlocks?: Block | InnerBlockTemplate[]; + + /** + * Example provides structured data for the block preview. You can set to `undefined` to disable + * the preview shown for the block type. + */ + example?: + | BlockExampleInnerBlock + | { + attributes: Attributes; + innerBlocks?: InnerBlockTemplate[]; + }; + + /** + * The list of scopes where the variation is applicable. When not provided, it assumes all available scopes. + */ + scope?: BlockVariationScope[]; + + /** + * An array of terms (which can be translated) that help users discover the variation while searching. + */ + keywords?: string[]; + + /** + * This can be a function or an array of block attributes. Function that accepts a block's + * attributes and the variation's attributes and determines if a variation is active. This + * function doesn't try to find a match dynamically based on all block's attributes, as in many + * cases some attributes are irrelevant. An example would be for `embed` block where we only care + * about `providerNameSlug` attribute's value. We can also use a `string[]` to tell which + * attributes should be compared as a shorthand. Each attributes will be matched and the variation + * will be active if all of them are matching. + */ + isActive?: + | ( ( + blockAttributes: Attributes, + variationAttributes: Attributes + ) => boolean ) + | string[]; +} diff --git a/packages/blocks/src/types/block.ts b/packages/blocks/src/types/block.ts new file mode 100644 index 0000000000000..1f75b1aeb4d20 --- /dev/null +++ b/packages/blocks/src/types/block.ts @@ -0,0 +1,87 @@ +/** + * Block Interface + * + * @module blocks/Block + */ + +/** + * Internal dependencies + */ +import type { BlockNode } from './block-node'; + +/** + * Instance of a [BlockType](./block-type.ts). + * + * @public + */ +export interface Block< Attributes extends Record< string, any > = {} > { + /** + * Name used to uniquely identify block type, e.g. core/paragraph. + * + * The block name comprises a namespace part and a name part separated + * by a "/". The namespace is usually the name of the plugin providing + * the block, for example, "myplugin/my-interesting-block". + * + * @see https://developer.wordpress.org/block-editor/reference-guides/block-api/block-registration/#block-name + */ + name: string; + + /** + * Description of block's attribute types. + * + * These define how to source the attributes for a block and + * may provide default values in case they aren't available. + * + * Example + * { + * "url": { + * "type": "string", + * "source": "attribute", + * "selector": "img", + * "attribute": "src" + * } + * } + * + * @see https://developer.wordpress.org/block-editor/reference-guides/block-api/block-attributes/ + */ + attributes: Attributes; + + /** + * Auto-generated ID unique to the loaded block inside the editor. + * + * Many functions in the editor reference blocks by their client id + * in order to modify or rearrange blocks. This is set when loading + * blocks and does not persist between edit sessions. + * + * Example: + * const clientId = select( blockEditorStore ).getSelectedBlockClientId(); + * const prevId = select( blockEditorStore ).getPreviousBlockClientId( clientId ); + * useDispatch( blockEditorStore ).replaceBlock( prevId, newBlock ); + */ + clientId: string; + + /** + * Array of inner blocks, if the block has any. + */ + innerBlocks: Block[]; + + /** + * Indicates whether or not the block is valid. + */ + isValid: boolean; + + /** + * Original block HTML from source document, used by the unrecognized block type. + */ + originalContent?: string; + + /** + * Contains descriptions of any block validation issues that appear in loading the block. + */ + validationIssues?: Array< Record< string, any > >; + + /** + * Un-processed original copy of block, used for preserving invalid blocks. + */ + __unstableBlockSource?: BlockNode; +} diff --git a/packages/blocks/src/types/index.ts b/packages/blocks/src/types/index.ts new file mode 100644 index 0000000000000..e447239ca6e98 --- /dev/null +++ b/packages/blocks/src/types/index.ts @@ -0,0 +1,12 @@ +export * from './block-attributes'; +export * from './block-category'; +export * from './block-collection'; +export * from './block-depreciation'; +export * from './block-icon'; +export * from './block-node'; +export * from './block-props'; +export * from './block-supports'; +export * from './block-type'; +export * from './block-variation'; +export * from './block'; +export * from './transform'; diff --git a/packages/blocks/src/types/transform.ts b/packages/blocks/src/types/transform.ts new file mode 100644 index 0000000000000..dfd60c10b6d2e --- /dev/null +++ b/packages/blocks/src/types/transform.ts @@ -0,0 +1,162 @@ +/** + * Block Transform Interfaces + * + * @module blocks/Transform + */ + +/** + * Internal dependencies + */ +import type { Block } from './block'; +import type { BlockType } from './block-type'; + +/** + * A content model used to validate and process pasted {@link TransformRaw raw} content. + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-transforms/#schemas-and-content-models Transforms Schema and Content Models} on developer.wordpress.org + * @public + */ +export type TransformRawSchema = { + [ k in keyof HTMLElementTagNameMap | '#text' ]?: { + attributes?: string[]; + require?: Array< keyof HTMLElementTagNameMap >; + classes?: Array< string | RegExp >; + children?: TransformRawSchema; + }; +}; + +/** + * Transform block into a different {@link BlockType }. + * + * Supports both _from_ and _to_ directions. + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-transforms/#block Transforms Block} on developer.wordpress.org + * @public + */ +export type TransformBlock< Attributes extends Record< string, any > > = { + type: 'block'; + blocks: string[]; + isMatch?( attributes: Attributes, block: string | string[] ): boolean; + isMultiBlock?: boolean; + transform( attributes: Attributes ): Block< Partial< Attributes > >; +}; + +/** + * Transform allowing blocks to be created from content introduced by the user. + * + * Supports the _from_ direction. Applied in a new block line after the user has introduced some + * content and hit the ENTER key. + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-transforms/#enter Transforms Enter} on developer.wordpress.org + * @public + */ +export type TransformEnter< Attributes extends Record< string, any > > = { + type: 'enter'; + regExp: RegExp; + transform(): Block< Partial< Attributes > >; +}; + +/** + * Transform allowing blocks to be created from files dropped into the editor. + * + * Supports the _from_ direction, + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-transforms/#files Transforms Files} on developer.wordpress.org + * @public + */ +export type TransformFiles< Attributes extends Record< string, any > > = { + type: 'files'; + isMatch?( files: FileList ): boolean; + transform( + files: FileList, + onChange?: ( id: string, attrs: Attributes ) => void + ): Block< Partial< Attributes > >; +}; + +/** + * Transform allowing blocks to be created from text typed by the user. + * + * Supports the _from_ direction. Applied when, in a new block line, the user types some text and + * then adds a trailing space. + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-transforms/#prefix Transforms Prefix} on developer.wordpress.org + * @public + */ +export type TransformPrefix< Attributes extends Record< string, any > > = { + type: 'prefix'; + prefix: string; + transform( content: string ): Block< Partial< Attributes > >; +}; + +/** + * Transform allowing blocks to be created from raw HTML nodes. + * + * Supports the _from_ direction. Applied when the user executes the “Convert to Blocks” action + * from within the block setting UI menu, as well as when some content is pasted or dropped into + * the editor. + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-transforms/#raw Transforms Raw} on developer.wordpress.org + * @public + */ +export type TransformRaw< Attributes extends Record< string, any > > = { + type: 'raw'; + /** + * Comma-separated list of selectors, no spaces. + * + * @example 'p,div,h1,.css-class,#id' + */ + selector?: string; + schema?: TransformRawSchema; + isMatch?( node: Node ): boolean; + transform?( node: Node ): Block< Partial< Attributes > > | void; +}; + +/** + * Transform allowing blocks to be created from shortcodes. + * + * Support the _from_ direction. Applied as part of the raw transformation process. + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-transforms/#shortcode Transforms Shortcode} on developer.wordpress.org + * @public + */ +export type TransformShortcode< Attributes extends Record< string, any > > = { + type: 'shortcode'; + tag: string; + transform?( + attributes: any, + match: Record< string, any > // TODO type shortcode + ): Block< Attributes >; + attributes?: any; // TODO find type +}; + +/** + * Transform a block to and from other blocks types, as well as from other entities. + * + * @see {@link https://developer.wordpress.org/block-editor/reference-guides/block-api/block-transforms/ Transforms} on developer.wordpress.org + * @public + */ +export type Transform< T extends Record< string, any > = {} > = ( + | TransformBlock< T > + | TransformEnter< T > + | TransformFiles< T > + | TransformPrefix< T > + | TransformRaw< T > + | TransformShortcode< T > +) & { + priority?: number; + + /** + * Whether there are any mobile block transforms. + * + * Used in [factory.js](../api/factory.js) + */ + usingMobileTransformations?: boolean; + + /** + * Function that defines how blocks are transformed from particular block types. + * + * @param blocks Block or Blocks to convert. + * @internal + */ + __experimentalConvert( blocks: Block | Block[] ): Block | Block[] | null; +}; diff --git a/packages/blocks/tsconfig.json b/packages/blocks/tsconfig.json new file mode 100644 index 0000000000000..af834313ecb94 --- /dev/null +++ b/packages/blocks/tsconfig.json @@ -0,0 +1,28 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "rootDir": "src", + "declarationDir": "build-types", + "noUnusedParameters": false, + "checkJs": false, + "noImplicitAny": false + }, + "references": [ + { "path": "../autop" }, + { "path": "../blob" }, + { "path": "../block-serialization-default-parser" }, + { "path": "../compose" }, + { "path": "../data" }, + { "path": "../deprecated" }, + { "path": "../dom" }, + { "path": "../element" }, + { "path": "../hooks" }, + { "path": "../html-entities" }, + { "path": "../i18n" }, + { "path": "../is-shallow-equal" }, + { "path": "../private-apis" }, + { "path": "../rich-text" } + ], + + "include": [ "src/**/*", "src/api/i18n-block.json" ] +} diff --git a/packages/core-data/src/entity-provider.js b/packages/core-data/src/entity-provider.js index 78eb05087d38a..2ff475df333d4 100644 --- a/packages/core-data/src/entity-provider.js +++ b/packages/core-data/src/entity-provider.js @@ -16,7 +16,7 @@ import { parse, __unstableSerializeAndClean } from '@wordpress/blocks'; import { STORE_NAME } from './name'; import { updateFootnotesFromMeta } from './footnotes'; -/** @typedef {import('@wordpress/blocks').WPBlock} WPBlock */ +/** @typedef {import('@wordpress/blocks').Block} WPBlock */ const EMPTY_ARRAY = []; diff --git a/packages/core-data/tsconfig.json b/packages/core-data/tsconfig.json index 0fb848f411d8e..b7e31a63eafd1 100644 --- a/packages/core-data/tsconfig.json +++ b/packages/core-data/tsconfig.json @@ -9,6 +9,7 @@ }, "references": [ { "path": "../api-fetch" }, + { "path": "../blocks" }, { "path": "../compose" }, { "path": "../block-editor" }, { "path": "../data" }, diff --git a/tsconfig.json b/tsconfig.json index 584ac01cb60c7..de789adfee3a5 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,6 +8,7 @@ { "path": "packages/block-editor" }, { "path": "packages/block-library" }, { "path": "packages/block-serialization-default-parser" }, + { "path": "packages/blocks" }, { "path": "packages/components" }, { "path": "packages/compose" }, { "path": "packages/core-data" },