Skip to content

Commit 86520b0

Browse files
committed
chore: add floating link editor
1 parent 022795f commit 86520b0

File tree

7 files changed

+648
-17
lines changed

7 files changed

+648
-17
lines changed

packages/root-cms/ui/components/RichTextEditor/LexicalEditor.tsx

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {InitialConfigType, LexicalComposer} from '@lexical/react/LexicalComposer
66
import {useLexicalComposerContext} from '@lexical/react/LexicalComposerContext';
77
import {ContentEditable} from '@lexical/react/LexicalContentEditable';
88
import {LexicalErrorBoundary} from '@lexical/react/LexicalErrorBoundary';
9+
import {LinkPlugin} from '@lexical/react/LexicalLinkPlugin';
910
import {ListPlugin} from '@lexical/react/LexicalListPlugin';
1011
import {HeadingNode} from '@lexical/rich-text';
1112
import {joinClassNames} from '../../utils/classes.js';
@@ -22,6 +23,7 @@ import {LexicalTheme} from './LexicalTheme.js';
2223
import {FloatingToolbarPlugin} from './plugins/FloatingToolbarPlugin.js';
2324
import {OnChangePlugin} from './plugins/OnChangePlugin.js';
2425
import {RichTextData} from '../../../shared/richtext.js';
26+
import {FloatingLinkEditorPlugin} from './plugins/FloatingLinkEditorPlugin.js';
2527

2628
const INITIAL_CONFIG: InitialConfigType = {
2729
namespace: 'RootCMS',
@@ -91,6 +93,7 @@ function Editor(props: EditorProps) {
9193

9294
return (
9395
<>
96+
<OnChangePlugin value={props.value} onChange={props.onChange} />
9497
<ToolbarPlugin
9598
editor={editor}
9699
activeEditor={activeEditor}
@@ -115,14 +118,23 @@ function Editor(props: EditorProps) {
115118
}
116119
ErrorBoundary={LexicalErrorBoundary}
117120
/>
121+
<LinkPlugin />
118122
<ListPlugin />
119123
<TabIndentationPlugin maxIndent={7} />
120124
<MarkdownTransformPlugin />
121-
<FloatingToolbarPlugin
122-
anchorElem={floatingAnchorElem!}
123-
setIsLinkEditMode={setIsLinkEditMode}
124-
/>
125-
<OnChangePlugin value={props.value} onChange={props.onChange} />
125+
{floatingAnchorElem && (
126+
<>
127+
<FloatingToolbarPlugin
128+
anchorElem={floatingAnchorElem}
129+
setIsLinkEditMode={setIsLinkEditMode}
130+
/>
131+
<FloatingLinkEditorPlugin
132+
anchorElem={floatingAnchorElem}
133+
isLinkEditMode={isLinkEditMode}
134+
setIsLinkEditMode={setIsLinkEditMode}
135+
/>
136+
</>
137+
)}
126138
</>
127139
);
128140
}

packages/root-cms/ui/components/RichTextEditor/LexicalTheme.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@
149149
}
150150
.LexicalTheme__link:hover {
151151
text-decoration: underline;
152+
text-underline-offset: 2px;
152153
cursor: pointer;
153154
}
154155
.LexicalTheme__blockCursor {
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
.LexicalEditor__linkEditor {
2+
display: flex;
3+
gap: 8px;
4+
align-items: center;
5+
position: absolute;
6+
top: 0;
7+
left: 0;
8+
z-index: 10;
9+
max-width: 400px;
10+
width: 100%;
11+
opacity: 0;
12+
background-color: #fff;
13+
padding: 8px;
14+
border: 1px solid rgb(233, 236, 239);
15+
box-shadow: rgba(0, 0, 0, 0.05) 0px 1px 3px, rgba(0, 0, 0, 0.05) 0px 20px 25px -5px, rgba(0, 0, 0, 0.04) 0px 10px 10px -5px;
16+
border-radius: 8px;
17+
transition: opacity 0.5s;
18+
will-change: transform;
19+
}
20+
21+
.LexicalEditor__link__input,
22+
.LexicalEditor__link__preview {
23+
flex: 1;
24+
display: block;
25+
border: 1px solid #dedede;
26+
position: relative;
27+
padding: 4px 8px;
28+
height: 28px;
29+
display: flex;
30+
align-items: center;
31+
font-family: var(--font-family-default);
32+
font-size: 12px;
33+
line-height: 1;
34+
}
35+
36+
.LexicalEditor__link__input:focus {
37+
outline: none;
38+
border-color: #339af0;
39+
}
40+
41+
.LexicalEditor__link__preview {
42+
overflow: auto;
43+
padding-right: 20px;
44+
}
45+
46+
.LexicalEditor__link__preview a {
47+
color: #216fdb;
48+
text-underline-offset: 2px;
49+
}
50+
51+
.LexicalEditor__link__preview svg {
52+
position: absolute;
53+
right: 8px;
54+
top: calc(50% - 8px);
55+
}
56+
57+
.LexicalEditor__link__controls {
58+
display: flex;
59+
gap: 4px;
60+
}
61+
62+
.LexicalEditor__link-editor .button {
63+
width: 20px;
64+
height: 20px;
65+
display: inline-block;
66+
padding: 6px;
67+
border-radius: 8px;
68+
cursor: pointer;
69+
margin: 0 2px;
70+
}
71+
72+
.LexicalEditor__link-editor .button.hovered {
73+
width: 20px;
74+
height: 20px;
75+
display: inline-block;
76+
background-color: #eee;
77+
}
78+
79+
.LexicalEditor__link-editor .button i {
80+
background-size: contain;
81+
display: inline-block;
82+
height: 20px;
83+
width: 20px;
84+
vertical-align: -0.25em;
85+
}

0 commit comments

Comments
 (0)