Skip to content
This repository was archived by the owner on Sep 9, 2024. It is now read-only.

Commit 316c8b6

Browse files
authored
fix: insert link for selected text behavior (#858)
1 parent 1fee800 commit 316c8b6

File tree

3 files changed

+30
-27
lines changed

3 files changed

+30
-27
lines changed

packages/core/src/components/common/button/Button.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ export interface BaseBaseProps {
1818
endIcon?: FC<{ className?: string }>;
1919
title?: string;
2020
'data-testid'?: string;
21+
onClick?: MouseEventHandler;
2122
}
2223

2324
export interface ButtonProps extends BaseBaseProps {
24-
onClick?: MouseEventHandler;
2525
disabled?: boolean;
2626
buttonRef?: Ref<HTMLButtonElement>;
2727
'aria-label'?: string;
@@ -81,6 +81,7 @@ const Button: FC<ButtonLinkProps> = ({
8181
title={title}
8282
data-testid={dataTestId}
8383
className={buttonClassNames}
84+
onClick={otherProps.onClick}
8485
style={style}
8586
>
8687
{content}
@@ -96,6 +97,7 @@ const Button: FC<ButtonLinkProps> = ({
9697
title={title}
9798
data-testid={dataTestId}
9899
className={buttonClassNames}
100+
onClick={otherProps.onClick}
99101
style={style}
100102
target="_blank"
101103
rel="noreferrer"
Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Link as LinkIcon } from '@styled-icons/material/Link';
22
import {
33
ELEMENT_LINK,
4+
deleteText,
45
getEditorString,
56
getNode,
67
getSelectionText,
@@ -9,7 +10,7 @@ import {
910
setNodes,
1011
someNode,
1112
} from '@udecode/plate';
12-
import React, { useCallback, useMemo, useState } from 'react';
13+
import React, { useCallback, useMemo } from 'react';
1314

1415
import useMediaInsert from '@staticcms/core/lib/hooks/useMediaInsert';
1516
import useUUID from '@staticcms/core/lib/hooks/useUUID';
@@ -21,7 +22,7 @@ import type { Collection, MarkdownField, MediaPath } from '@staticcms/core/inter
2122
import type { MdLinkElement } from '@staticcms/markdown/plate/plateTypes';
2223
import type { TText } from '@udecode/plate';
2324
import type { FC } from 'react';
24-
import type { Path } from 'slate';
25+
import type { Location } from 'slate';
2526

2627
export interface InsertLinkToolbarButtonProps {
2728
variant: 'button' | 'menu';
@@ -38,25 +39,25 @@ const InsertLinkToolbarButton: FC<InsertLinkToolbarButtonProps> = ({
3839
currentValue,
3940
disabled,
4041
}) => {
41-
const [selection, setSelection] = useState<Path>();
4242
const editor = useMdPlateEditorState();
4343
const handleInsert = useCallback(
4444
({ path: newUrl, alt: newText }: MediaPath<string>) => {
45-
if (isNotEmpty(newUrl) && selection) {
45+
const selectionPoint = editor.selection?.focus.path;
46+
if (isNotEmpty(newUrl) && selectionPoint) {
4647
const text = isNotEmpty(newText) ? newText : newUrl;
47-
const linkAt = getNode<MdLinkElement>(editor, selection);
48+
const linkAt = getNode<MdLinkElement>(editor, selectionPoint);
4849

4950
if (linkAt && linkAt.type === ELEMENT_LINK) {
5051
if (newUrl !== linkAt.url || text !== linkAt.children[0].text) {
5152
setNodes<MdLinkElement>(
5253
editor,
5354
{ url: newUrl, children: [{ text: newText }] },
54-
{ at: selection },
55+
{ at: selectionPoint },
5556
);
5657

57-
if (text !== getEditorString(editor, selection)) {
58+
if (text !== getEditorString(editor, selectionPoint)) {
5859
replaceNodeChildren<TText>(editor, {
59-
at: selection,
60+
at: selectionPoint,
6061
nodes: { text },
6162
insertOptions: {
6263
select: true,
@@ -68,32 +69,29 @@ const InsertLinkToolbarButton: FC<InsertLinkToolbarButtonProps> = ({
6869
return;
6970
}
7071

72+
console.log('editor.selection', editor.selection);
73+
74+
deleteText(editor, {
75+
at: editor.selection as unknown as Location,
76+
});
77+
7178
insertLink(
7279
editor,
7380
{ url: newUrl, text },
7481
{
75-
at: selection,
82+
at: editor.selection as unknown as Location,
7683
},
7784
);
78-
const newSelection = [...selection];
79-
const lastIndex = newSelection.pop() ?? 0;
80-
setSelection([...newSelection, lastIndex + 1]);
8185
}
8286
},
83-
[editor, selection],
87+
[editor],
8488
);
8589

8690
const chooseUrl = useMemo(() => field.choose_url ?? true, [field.choose_url]);
8791

8892
const isLink = !!editor?.selection && someNode(editor, { match: { type: ELEMENT_LINK } });
8993

90-
const selectedText: string = useMemo(() => {
91-
if (!editor.selection) {
92-
return '';
93-
}
94-
95-
return getSelectionText(editor);
96-
}, [editor]);
94+
const selectedText = !editor.selection ? '' : getSelectionText(editor);
9795

9896
const controlID = useUUID();
9997
const openMediaLibrary = useMediaInsert(
@@ -106,21 +104,19 @@ const InsertLinkToolbarButton: FC<InsertLinkToolbarButtonProps> = ({
106104
);
107105

108106
const handleOpenMediaLibrary = useCallback(() => {
109-
setSelection(editor.selection?.focus.path);
110107
openMediaLibrary();
111-
}, [editor.selection, openMediaLibrary]);
108+
}, [openMediaLibrary]);
112109

113-
return (
110+
return !isLink ? (
114111
<ToolbarButton
115112
label="Link"
116113
tooltip="Insert link"
117114
icon={LinkIcon}
118115
onClick={handleOpenMediaLibrary}
119-
active={isLink}
120116
disabled={disabled}
121117
variant={variant}
122118
/>
123-
);
119+
) : null;
124120
};
125121

126122
export default InsertLinkToolbarButton;

packages/core/src/widgets/markdown/plate/components/common/MediaPopover.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import type {
1313
MarkdownField,
1414
MediaPath,
1515
} from '@staticcms/core/interface';
16+
import type { MouseEvent } from 'react';
1617

1718
export interface MediaPopoverProps<T extends FileOrImageField | MarkdownField> {
1819
anchorEl: HTMLElement | null;
@@ -69,6 +70,10 @@ const MediaPopover = <T extends FileOrImageField | MarkdownField>({
6970
handleMediaChange,
7071
);
7172

73+
const noop = useCallback((event: MouseEvent) => {
74+
event.stopPropagation();
75+
}, []);
76+
7277
const open = Boolean(anchorEl);
7378
const id = open ? 'edit-popover' : undefined;
7479

@@ -122,7 +127,7 @@ const MediaPopover = <T extends FileOrImageField | MarkdownField>({
122127
"
123128
/>
124129
{!forImage ? (
125-
<Button href={url} variant="text" size="small">
130+
<Button href={url} variant="text" size="small" onClick={noop}>
126131
<OpenInNewIcon className="w-4 h-4" title="Open In New Tab" />
127132
</Button>
128133
) : null}

0 commit comments

Comments
 (0)