feat: Inlinemenu double link interaction
This commit is contained in:
@@ -6,6 +6,7 @@ import { RenderElementProps } from 'slate-react';
|
|||||||
|
|
||||||
export type DoubleLinkElement = {
|
export type DoubleLinkElement = {
|
||||||
type: 'link';
|
type: 'link';
|
||||||
|
linkType: 'doubleLink';
|
||||||
workspaceId: string;
|
workspaceId: string;
|
||||||
blockId: string;
|
blockId: string;
|
||||||
children: Descendant[];
|
children: Descendant[];
|
||||||
|
|||||||
@@ -137,7 +137,8 @@ export const DoubleLinkMenu = ({
|
|||||||
|
|
||||||
const resetState = useCallback(
|
const resetState = useCallback(
|
||||||
(preNodeId: string, nextNodeId: string) => {
|
(preNodeId: string, nextNodeId: string) => {
|
||||||
editor.blockHelper.removeDoubleLinkSearchSlash(preNodeId);
|
preNodeId &&
|
||||||
|
editor.blockHelper.removeDoubleLinkSearchSlash(preNodeId);
|
||||||
setCurBlockId(nextNodeId);
|
setCurBlockId(nextNodeId);
|
||||||
setSearchText('');
|
setSearchText('');
|
||||||
setIsOpen(true);
|
setIsOpen(true);
|
||||||
@@ -206,7 +207,7 @@ export const DoubleLinkMenu = ({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[editor, isOpen, curBlockId, hideMenu]
|
[editor, isOpen, curBlockId, hideMenu, resetState]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleKeyup = useCallback(
|
const handleKeyup = useCallback(
|
||||||
@@ -251,6 +252,20 @@ export const DoubleLinkMenu = ({
|
|||||||
};
|
};
|
||||||
}, [handleKeyup, handleKeyDown, hooks]);
|
}, [handleKeyup, handleKeyDown, hooks]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const showDoubleLink = () => {
|
||||||
|
const { anchorNode } = editor.selection.currentSelectInfo;
|
||||||
|
editor.blockHelper.insertNodes(anchorNode.id, [{ text: '[[' }], {
|
||||||
|
select: true,
|
||||||
|
});
|
||||||
|
setTimeout(() => {
|
||||||
|
resetState('', anchorNode.id);
|
||||||
|
}, 0);
|
||||||
|
};
|
||||||
|
editor.plugins.observe('showDoubleLink', showDoubleLink);
|
||||||
|
return () => editor.plugins.unobserve('showDoubleLink', showDoubleLink);
|
||||||
|
}, [editor, resetState]);
|
||||||
|
|
||||||
const insertDoubleLink = useCallback(
|
const insertDoubleLink = useCallback(
|
||||||
async (pageId: string) => {
|
async (pageId: string) => {
|
||||||
editor.blockHelper.setSelectDoubleLinkSearchSlash(curBlockId);
|
editor.blockHelper.setSelectDoubleLinkSearchSlash(curBlockId);
|
||||||
@@ -328,46 +343,48 @@ export const DoubleLinkMenu = ({
|
|||||||
...doubleLinkMenuStyle,
|
...doubleLinkMenuStyle,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<MuiClickAwayListener onClickAway={() => hideMenu()}>
|
{isOpen && (
|
||||||
<Popper
|
<MuiClickAwayListener onClickAway={() => hideMenu()}>
|
||||||
open={isOpen}
|
<Popper
|
||||||
anchorEl={anchorEl}
|
open={isOpen}
|
||||||
transition
|
anchorEl={anchorEl}
|
||||||
placement="bottom-start"
|
transition
|
||||||
>
|
placement="bottom-start"
|
||||||
{({ TransitionProps }) => (
|
>
|
||||||
<Grow
|
{({ TransitionProps }) => (
|
||||||
{...TransitionProps}
|
<Grow
|
||||||
style={{
|
{...TransitionProps}
|
||||||
transformOrigin: 'left bottom',
|
style={{
|
||||||
}}
|
transformOrigin: 'left bottom',
|
||||||
>
|
}}
|
||||||
<Paper>
|
>
|
||||||
{inAddNewPage && (
|
<Paper>
|
||||||
<NewPageSearchContainer>
|
{inAddNewPage && (
|
||||||
<Input
|
<NewPageSearchContainer>
|
||||||
ref={newPageSearchRef}
|
<Input
|
||||||
value={filterText}
|
ref={newPageSearchRef}
|
||||||
onChange={handleFilterChange}
|
value={filterText}
|
||||||
placeholder="Search page to add to..."
|
onChange={handleFilterChange}
|
||||||
/>
|
placeholder="Search page to add to..."
|
||||||
</NewPageSearchContainer>
|
/>
|
||||||
)}
|
</NewPageSearchContainer>
|
||||||
<DoubleLinkMenuContainer
|
)}
|
||||||
editor={editor}
|
<DoubleLinkMenuContainer
|
||||||
hooks={hooks}
|
editor={editor}
|
||||||
style={style}
|
hooks={hooks}
|
||||||
blockId={curBlockId}
|
style={style}
|
||||||
onSelected={handleSelected}
|
blockId={curBlockId}
|
||||||
onClose={hideMenu}
|
onSelected={handleSelected}
|
||||||
items={menuItems}
|
onClose={hideMenu}
|
||||||
types={menuTypes}
|
items={menuItems}
|
||||||
/>
|
types={menuTypes}
|
||||||
</Paper>
|
/>
|
||||||
</Grow>
|
</Paper>
|
||||||
)}
|
</Grow>
|
||||||
</Popper>
|
)}
|
||||||
</MuiClickAwayListener>
|
</Popper>
|
||||||
|
</MuiClickAwayListener>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
|
import { Tooltip } from '@toeverything/components/ui';
|
||||||
import React, { useCallback } from 'react';
|
import React, { useCallback } from 'react';
|
||||||
import style9 from 'style9';
|
import style9 from 'style9';
|
||||||
|
|
||||||
import type { IconItemType, WithEditorSelectionType } from '../types';
|
|
||||||
import { inlineMenuNamesKeys, inlineMenuShortcuts } from '../config';
|
import { inlineMenuNamesKeys, inlineMenuShortcuts } from '../config';
|
||||||
import { Tooltip } from '@toeverything/components/ui';
|
import type { IconItemType, WithEditorSelectionType } from '../types';
|
||||||
|
|
||||||
type MenuIconItemProps = IconItemType & WithEditorSelectionType;
|
type MenuIconItemProps = IconItemType & WithEditorSelectionType;
|
||||||
|
|
||||||
export const MenuIconItem = ({
|
export const MenuIconItem = ({
|
||||||
@@ -22,6 +22,7 @@ export const MenuIconItem = ({
|
|||||||
editor,
|
editor,
|
||||||
type: nameKey,
|
type: nameKey,
|
||||||
anchorNodeId: selectionInfo?.anchorNode?.id,
|
anchorNodeId: selectionInfo?.anchorNode?.id,
|
||||||
|
setShow,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if ([inlineMenuNamesKeys.comment].includes(nameKey)) {
|
if ([inlineMenuNamesKeys.comment].includes(nameKey)) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { SvgIconProps } from '@toeverything/components/ui';
|
import type { SvgIconProps } from '@toeverything/components/ui';
|
||||||
import type { Virgo, SelectionInfo } from '@toeverything/framework/virgo';
|
import type { SelectionInfo, Virgo } from '@toeverything/framework/virgo';
|
||||||
import { inlineMenuNames, INLINE_MENU_UI_TYPES } from './config';
|
import { inlineMenuNames, INLINE_MENU_UI_TYPES } from './config';
|
||||||
|
|
||||||
export type WithEditorSelectionType = {
|
export type WithEditorSelectionType = {
|
||||||
@@ -14,10 +14,12 @@ export type ClickItemHandler = ({
|
|||||||
type,
|
type,
|
||||||
editor,
|
editor,
|
||||||
anchorNodeId,
|
anchorNodeId,
|
||||||
|
setShow,
|
||||||
}: {
|
}: {
|
||||||
type: InlineMenuNamesType;
|
type: InlineMenuNamesType;
|
||||||
editor: Virgo;
|
editor: Virgo;
|
||||||
anchorNodeId: string;
|
anchorNodeId: string;
|
||||||
|
setShow?: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
}) => void;
|
}) => void;
|
||||||
|
|
||||||
export type IconItemType = {
|
export type IconItemType = {
|
||||||
|
|||||||
@@ -107,6 +107,7 @@ const common_handler_for_inline_menu: ClickItemHandler = ({
|
|||||||
editor,
|
editor,
|
||||||
anchorNodeId,
|
anchorNodeId,
|
||||||
type,
|
type,
|
||||||
|
setShow,
|
||||||
}) => {
|
}) => {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case inlineMenuNamesKeys.text:
|
case inlineMenuNamesKeys.text:
|
||||||
@@ -438,6 +439,10 @@ const common_handler_for_inline_menu: ClickItemHandler = ({
|
|||||||
blockType: Protocol.Block.Type.file,
|
blockType: Protocol.Block.Type.file,
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
case inlineMenuNamesKeys.backlinks:
|
||||||
|
editor.plugins.emit('showDoubleLink');
|
||||||
|
setShow(false);
|
||||||
|
break;
|
||||||
default: // do nothing
|
default: // do nothing
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user