From cbcbf41da512b93dc4271d4428faab34aafd389b Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Fri, 12 Jan 2024 09:54:53 +0000 Subject: [PATCH] Add privateApis to RichText package and export useAnchorWithUpdate hook --- package-lock.json | 2 + packages/private-apis/src/implementation.js | 1 + packages/rich-text/README.md | 4 ++ packages/rich-text/package.json | 1 + .../rich-text/src/component/use-anchor.js | 55 ++++++++++--------- packages/rich-text/src/index.ts | 2 + packages/rich-text/src/lock-unlock.js | 10 ++++ packages/rich-text/src/private-apis.js | 13 +++++ 8 files changed, 62 insertions(+), 26 deletions(-) create mode 100644 packages/rich-text/src/lock-unlock.js create mode 100644 packages/rich-text/src/private-apis.js diff --git a/package-lock.json b/package-lock.json index 02de0a60ff4c93..4c74b0dd448cb2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -55925,6 +55925,7 @@ "@wordpress/escape-html": "file:../escape-html", "@wordpress/i18n": "file:../i18n", "@wordpress/keycodes": "file:../keycodes", + "@wordpress/private-apis": "file:../private-apis", "memize": "^2.1.0", "rememo": "^4.0.2" }, @@ -70473,6 +70474,7 @@ "@wordpress/escape-html": "file:../escape-html", "@wordpress/i18n": "file:../i18n", "@wordpress/keycodes": "file:../keycodes", + "@wordpress/private-apis": "file:../private-apis", "memize": "^2.1.0", "rememo": "^4.0.2" } diff --git a/packages/private-apis/src/implementation.js b/packages/private-apis/src/implementation.js index 619478cf76386d..de109e06a8da31 100644 --- a/packages/private-apis/src/implementation.js +++ b/packages/private-apis/src/implementation.js @@ -27,6 +27,7 @@ const CORE_MODULES_USING_PRIVATE_APIS = [ '@wordpress/format-library', '@wordpress/patterns', '@wordpress/reusable-blocks', + '@wordpress/rich-text', '@wordpress/router', '@wordpress/dataviews', ]; diff --git a/packages/rich-text/README.md b/packages/rich-text/README.md index 90fd15e1c905c5..ac58e81fa5d84b 100644 --- a/packages/rich-text/README.md +++ b/packages/rich-text/README.md @@ -299,6 +299,10 @@ _Returns_ - `RichTextValue`: A new combined value. +### privateApis + +Private @wordpress/block-editor APIs. + ### registerFormatType Registers a new format provided a unique name and an object defining its behavior. diff --git a/packages/rich-text/package.json b/packages/rich-text/package.json index 645beb47bfa2a6..9f7c152ea6e172 100644 --- a/packages/rich-text/package.json +++ b/packages/rich-text/package.json @@ -39,6 +39,7 @@ "@wordpress/escape-html": "file:../escape-html", "@wordpress/i18n": "file:../i18n", "@wordpress/keycodes": "file:../keycodes", + "@wordpress/private-apis": "file:../private-apis", "memize": "^2.1.0", "rememo": "^4.0.2" }, diff --git a/packages/rich-text/src/component/use-anchor.js b/packages/rich-text/src/component/use-anchor.js index ce571858a9b99f..8cfdedb6d1474f 100644 --- a/packages/rich-text/src/component/use-anchor.js +++ b/packages/rich-text/src/component/use-anchor.js @@ -86,18 +86,6 @@ function createVirtualAnchorElement( range, editableContentElement ) { }; } -/** - * Get the anchor: a format element if there is a matching one based on the - * tagName and className or a range otherwise. - * - * @param {HTMLElement} editableContentElement The editable wrapper. - * @param {string} tagName The tag name of the format - * element. - * @param {string} className The class name of the format - * element. - * - * @return {HTMLElement|VirtualAnchorElement|undefined} The anchor. - */ function getAnchor( editableContentElement, tagName, className ) { if ( ! editableContentElement ) return; @@ -124,19 +112,7 @@ function getAnchor( editableContentElement, tagName, className ) { return createVirtualAnchorElement( range, editableContentElement ); } -/** - * This hook, to be used in a format type's Edit component, returns the active - * element that is formatted, or a virtual element for the selection range if - * no format is active. The returned value is meant to be used for positioning - * UI, e.g. by passing it to the `Popover` component via the `anchor` prop. - * - * @param {Object} $1 Named parameters. - * @param {HTMLElement|null} $1.editableContentElement The element containing - * the editable content. - * @param {WPFormat=} $1.settings The format type's settings. - * @return {Element|VirtualAnchorElement|undefined|null} The active element or selection range. - */ -export function useAnchor( { editableContentElement, settings = {} } ) { +function useAnchorBase( { editableContentElement, settings = {} } ) { const { tagName, className } = settings; const [ anchor, setAnchor ] = useState( () => getAnchor( editableContentElement, tagName, className ) @@ -174,6 +150,33 @@ export function useAnchor( { editableContentElement, settings = {} } ) { }; }, [ editableContentElement, tagName, className, callback ] ); - anchor.update = callback; + return { + anchor, + update: callback, + }; +} + +/** + * This hook, to be used in a format type's Edit component, returns the active + * element that is formatted, or a virtual element for the selection range if + * no format is active. The returned value is meant to be used for positioning + * UI, e.g. by passing it to the `Popover` component via the `anchor` prop. + * + * @param {Object} $1 Named parameters. + * @param {HTMLElement|null} $1.editableContentElement The element containing + * the editable content. + * @param {WPFormat=} $1.settings The format type's settings. + * @return {Element|VirtualAnchorElement|undefined|null} The active element or selection range. + */ +export function useAnchor( { editableContentElement, settings = {} } ) { + const { anchor } = useAnchorBase( { editableContentElement, settings } ); + return anchor; } + +export function useAnchorWithUpdate( { + editableContentElement, + settings = {}, +} ) { + return useAnchorBase( { editableContentElement, settings } ); +} diff --git a/packages/rich-text/src/index.ts b/packages/rich-text/src/index.ts index f82317d81573d0..57f8bad762628b 100644 --- a/packages/rich-text/src/index.ts +++ b/packages/rich-text/src/index.ts @@ -36,3 +36,5 @@ export { * documentation for more information. */ export type { RichTextValue } from './types'; + +export { privateApis } from './private-apis'; diff --git a/packages/rich-text/src/lock-unlock.js b/packages/rich-text/src/lock-unlock.js new file mode 100644 index 00000000000000..fa8c56b7d3ff64 --- /dev/null +++ b/packages/rich-text/src/lock-unlock.js @@ -0,0 +1,10 @@ +/** + * WordPress dependencies + */ +import { __dangerousOptInToUnstableAPIsOnlyForCoreModules } from '@wordpress/private-apis'; + +export const { lock, unlock } = + __dangerousOptInToUnstableAPIsOnlyForCoreModules( + 'I know using unstable features means my theme or plugin will inevitably break in the next version of WordPress.', + '@wordpress/rich-text' + ); diff --git a/packages/rich-text/src/private-apis.js b/packages/rich-text/src/private-apis.js new file mode 100644 index 00000000000000..398ffb40651460 --- /dev/null +++ b/packages/rich-text/src/private-apis.js @@ -0,0 +1,13 @@ +/** + * Internal dependencies + */ +import { useAnchorWithUpdate } from './component/use-anchor'; +import { lock } from './lock-unlock'; + +/** + * Private @wordpress/block-editor APIs. + */ +export const privateApis = {}; +lock( privateApis, { + useAnchorWithUpdate, +} );