improve bubble-menu placement

This commit is contained in:
fantasticit 2022-11-28 17:33:30 +08:00
parent b2a485e513
commit 1d32808335
3 changed files with 26 additions and 8 deletions

View File

@ -19,9 +19,8 @@ export interface BubbleMenuPluginProps {
to?: number;
}) => boolean)
| null;
renderContainerSelector?: string;
matchRenderContainer?: (node: HTMLElement) => boolean;
getRenderContainer?: (node: HTMLElement) => HTMLElement;
defaultAnimation?: boolean;
}
export type BubbleMenuViewProps = BubbleMenuPluginProps & {
@ -43,6 +42,8 @@ export class BubbleMenuView {
public getRenderContainer?: BubbleMenuPluginProps['getRenderContainer'];
public defaultAnimation?: BubbleMenuPluginProps['defaultAnimation'];
public shouldShow: Exclude<BubbleMenuPluginProps['shouldShow'], null> = ({ view, state, from, to }) => {
const { doc, selection } = state;
const { empty } = selection;
@ -59,11 +60,20 @@ export class BubbleMenuView {
return true;
};
constructor({ editor, element, view, tippyOptions = {}, shouldShow, getRenderContainer }: BubbleMenuViewProps) {
constructor({
editor,
element,
view,
tippyOptions = {},
shouldShow,
getRenderContainer,
defaultAnimation = true,
}: BubbleMenuViewProps) {
this.editor = editor;
this.element = element;
this.view = view;
this.getRenderContainer = getRenderContainer;
this.defaultAnimation = defaultAnimation;
if (shouldShow) {
this.shouldShow = shouldShow;
@ -133,7 +143,13 @@ export class BubbleMenuView {
placement: 'top',
hideOnClick: 'toggle',
...Object.assign(
{ zIndex: 999, duration: 200, animation: 'shift-toward-subtle', moveTransition: 'transform 0.2s ease-in-out' },
{
zIndex: 999,
duration: 200,
...(this.defaultAnimation
? { animation: 'shift-toward-subtle', moveTransition: 'transform 0.2s ease-in-out' }
: {}),
},
this.tippyOptions
),
});
@ -159,8 +175,10 @@ export class BubbleMenuView {
// support for CellSelections
const { ranges } = selection;
const cursorAt = selection.$anchor.pos;
const from = Math.min(...ranges.map((range) => range.$from.pos));
const to = Math.max(...ranges.map((range) => range.$to.pos));
const placement = Math.abs(cursorAt - to) <= Math.abs(cursorAt - from) ? 'bottom' : 'top';
const domAtPos = view.domAtPos(from).node as HTMLElement;
const nodeDOM = view.nodeDOM(from) as HTMLElement;
const node = nodeDOM || domAtPos;
@ -183,6 +201,7 @@ export class BubbleMenuView {
}
this.tippy?.setProps({
placement,
getReferenceClientRect: () => {
let toMountNode = null;

View File

@ -25,9 +25,8 @@ export const BubbleMenu: React.FC<BubbleMenuProps> = (props) => {
editor,
tippyOptions = {},
shouldShow = null,
// renderContainerSelector,
// matchRenderContainer,
getRenderContainer,
defaultAnimation,
} = props;
const plugin = BubbleMenuPlugin({
@ -36,9 +35,8 @@ export const BubbleMenu: React.FC<BubbleMenuProps> = (props) => {
element,
tippyOptions,
shouldShow,
// renderContainerSelector,
// matchRenderContainer,
getRenderContainer,
defaultAnimation,
});
editor.registerPlugin(plugin);

View File

@ -65,6 +65,7 @@ export const Text = ({ editor }) => {
pluginKey="text-bubble-menu"
shouldShow={shouldShow}
tippyOptions={{ maxWidth: 'calc(100vw - 100px)' }}
defaultAnimation={false}
>
<Space spacing={4}>
<Bold editor={editor} />