Skip to content

Commit

Permalink
useAnchorRef: return a VirtualElement instead of a range
Browse files Browse the repository at this point in the history
  • Loading branch information
ciampo committed Sep 1, 2022
1 parent 1de32a8 commit 35b2ce9
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 8 deletions.
6 changes: 3 additions & 3 deletions packages/rich-text/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -477,9 +477,9 @@ _Returns_
### useAnchorRef

This hook, to be used in a format type's Edit component, returns the active
element that is formatted, or 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.
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.

_Parameters_

Expand Down
21 changes: 16 additions & 5 deletions packages/rich-text/src/component/use-anchor-ref.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,25 @@ import { getActiveFormat } from '../get-active-format';
/** @typedef {import('../register-format-type').RichTextFormatType} RichTextFormatType */
/** @typedef {import('../create').RichTextValue} RichTextValue */

/**
* @typedef {Object} VirtualAnchorElement
* @property {Function} getBoundingClientRect A function returning a DOMRect
* @property {Document} ownerDocument The element's ownerDocument
*/

/**
* This hook, to be used in a format type's Edit component, returns the active
* element that is formatted, or 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.
* 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.
*
* @param {Object} $1 Named parameters.
* @param {RefObject<HTMLElement>} $1.ref React ref of the element
* containing the editable content.
* @param {RichTextValue} $1.value Value to check for selection.
* @param {RichTextFormatType} $1.settings The format type's settings.
*
* @return {Element|Range} The active element or selection range.
* @return {Element|VirtualAnchorElement|null|undefined} The active element or selection range.
*/
export function useAnchorRef( { ref, value, settings = {} } ) {
const { tagName, className, name } = settings;
Expand All @@ -44,7 +50,12 @@ export function useAnchorRef( { ref, value, settings = {} } ) {
const range = selection.getRangeAt( 0 );

if ( ! activeFormat ) {
return range;
return {
ownerDocument: range.startContainer.ownerDocument,
getBoundingClientRect() {
return range.getBoundingClientRect();
},
};
}

let element = range.startContainer;
Expand Down

0 comments on commit 35b2ce9

Please sign in to comment.