WordPress Gutenberg Popover, how to position at the cursor when text is selected? #51307
Answered
by
bmarshall511
bmarshall511
asked this question in
Q&A
-
Been battling this for almost a day now with no luck. I'm trying to position a Popover based off the user's cursor. Got it working when no text is selected, but when text is selected, no joy. Here's what I've got: import {
registerFormatType,
toggleFormat,
useAnchorRef,
} from '@wordpress/rich-text';
import { Fragment } from '@wordpress/element';
import { BlockControls, RichTextShortcut } from '@wordpress/block-editor';
import { Popover, ToolbarButton, ToolbarGroup } from '@wordpress/components';
import { displayShortcut } from '@wordpress/keycodes';
import { __ } from '@wordpress/i18n';
const InsertMyPopup = {
name: 'insertmypopup',
title: __('My Popup'),
character: 'o',
value: '',
};
const { name, title, character } = InsertMyPopup;
const type = `my-popup/${name}`;
registerFormatType(type, {
title,
tagName: name,
className: null,
active: false,
edit({ isActive, value, onChange, contentRef }) {
const anchorRef = useAnchorRef({ ref: contentRef, value });
const onToggle = () => {
onChange(toggleFormat(value, { type }));
};
const thePopover = isActive && (
<Popover
placement='bottom-start'
focusOnMount='firstElement'
key='my-popover'
expandOnMobile={true}
headerTitle={__(
'My Popup',
'insert-my-popup'
)}
onClose={() => {
onChange(toggleFormat(value, { type }));
}}
anchorRef={anchorRef}
>
Popup
</Popover>
);
return (
<Fragment>
<BlockControls group='other'>
<ToolbarGroup>
<ToolbarButton
icon='editor-customchar'
isPressed={isActive}
label={title}
onClick={onToggle}
shortcut={displayShortcut.primary(character)}
/>
</ToolbarGroup>
</BlockControls>
<Fragment>
<RichTextShortcut
type='primary'
character={character}
onUse={onToggle}
contentRef={contentRef}
/>
</Fragment>
{thePopover}
</Fragment>
);
},
}); |
Beta Was this translation helpful? Give feedback.
Answered by
bmarshall511
Jun 9, 2023
Replies: 1 comment
-
After 2 days, finally got it figured out, got rid of the import {
registerFormatType,
toggleFormat
} from '@wordpress/rich-text';
import { Fragment } from '@wordpress/element';
import { BlockControls, RichTextShortcut } from '@wordpress/block-editor';
import { Popover, ToolbarButton, ToolbarGroup } from '@wordpress/components';
import { displayShortcut } from '@wordpress/keycodes';
import { __ } from '@wordpress/i18n';
const InsertMyPopup = {
name: 'insertmypopup',
title: __('My Popup'),
character: 'o',
value: '',
};
const { name, title, character } = InsertMyPopup;
const type = `my-popup/${name}`;
let anchorRange;
let anchorRect;
registerFormatType(type, {
title,
tagName: name,
className: null,
active: false,
edit({ isActive, value, onChange, contentRef }) {
const onToggle = () => {
// Set up the anchorRange when the Popover is opened.
const selection = document.defaultView.getSelection();
anchorRange =
selection.rangeCount > 0 ? selection.getRangeAt(0) : null;
// Pin the Popover to the caret position.
const boundingClientRect = anchorRange
? anchorRange.getBoundingClientRect()
: null;
anchorRect = anchorRange ? () => boundingClientRect : null;
onChange(toggleFormat(value, { type }));
};
const thePopover = isActive && (
<Popover
placement='bottom-start'
focusOnMount='firstElement'
key='my-popover'
expandOnMobile={true}
headerTitle={__(
'My Popup',
'insert-my-popup'
)}
onClose={() => {
onChange(toggleFormat(value, { type }));
}}
getAnchorRect={anchorRect}
>
Popup
</Popover>
);
return (
<Fragment>
<BlockControls group='other'>
<ToolbarGroup>
<ToolbarButton
icon='editor-customchar'
isPressed={isActive}
label={title}
onClick={onToggle}
shortcut={displayShortcut.primary(character)}
/>
</ToolbarGroup>
</BlockControls>
<Fragment>
<RichTextShortcut
type='primary'
character={character}
onUse={onToggle}
contentRef={contentRef}
/>
</Fragment>
{thePopover}
</Fragment>
);
},
}); |
Beta Was this translation helpful? Give feedback.
0 replies
Answer selected by
bmarshall511
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
After 2 days, finally got it figured out, got rid of the
useAnchorRef
and created a var foranchorRange
&anchorRect
to store the positioning. Would still love to find a way to use the new propanchor
instead of the deprecated propanchor
for thePopover
component. I'll leave this ? open in hopes someone has an idea.