Skip to content

Commit 6fab4b2

Browse files
committed
feat: 添加浮动文本格式工具栏插件
1 parent 2fcf597 commit 6fab4b2

5 files changed

Lines changed: 567 additions & 14 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@copus/editor",
3-
"version": "0.21.0-19",
3+
"version": "0.21.0-20",
44
"type": "module",
55
"publishConfig": {
66
"access": "public"

src/Editor.tsx

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import ContextMenuPlugin from './plugins/ContextMenuPlugin';
3636
import DragDropPaste from './plugins/DragDropPastePlugin';
3737
import DraggableBlockPlugin from './plugins/DraggableBlockPlugin';
3838
import FloatingLinkEditorPlugin from './plugins/FloatingLinkEditorPlugin';
39+
import FloatingTextFormatToolbarPlugin from './plugins/FloatingTextFormatToolbarPlugin';
3940
import FloatingCopusToolbarPlugin from './plugins/FloatingCopusToolbarPlugin';
4041
import ImagesPlugin from './plugins/ImagesPlugin';
4142
import InlineImagePlugin from './plugins/InlineImagePlugin';
@@ -114,6 +115,23 @@ export default function Editor({ onChange, readOnly, toolbar, showLabel, copus =
114115
const placeholder = <Placeholder>{text}</Placeholder>;
115116
const [floatingAnchorElem, setFloatingAnchorElem] = useState<HTMLDivElement | null>(null);
116117
const [isLinkEditMode, setIsLinkEditMode] = useState<boolean>(false);
118+
const [isSmallWidthViewport, setIsSmallWidthViewport] = useState<boolean>(false);
119+
120+
useEffect(() => {
121+
const updateViewPortWidth = () => {
122+
const isNextSmallWidthViewport = CAN_USE_DOM && window.matchMedia('(max-width: 1025px)').matches;
123+
124+
if (isNextSmallWidthViewport !== isSmallWidthViewport) {
125+
setIsSmallWidthViewport(isNextSmallWidthViewport);
126+
}
127+
};
128+
updateViewPortWidth();
129+
window.addEventListener('resize', updateViewPortWidth);
130+
131+
return () => {
132+
window.removeEventListener('resize', updateViewPortWidth);
133+
};
134+
}, [isSmallWidthViewport]);
117135

118136
const onRef = (_floatingAnchorElem: HTMLDivElement) => {
119137
if (_floatingAnchorElem !== null) {
@@ -150,15 +168,15 @@ export default function Editor({ onChange, readOnly, toolbar, showLabel, copus =
150168
return (
151169
<div className="editor-container plain-text editor-read-only">
152170
{/* <PhotoProvider maskOpacity={0.5}> */}
153-
<PlainTextPlugin
154-
contentEditable={
155-
<div ref={onRef}>
156-
<ContentEditable />
157-
</div>
158-
}
159-
// placeholder={placeholder}
160-
ErrorBoundary={LexicalErrorBoundary}
161-
/>
171+
<PlainTextPlugin
172+
contentEditable={
173+
<div ref={onRef}>
174+
<ContentEditable />
175+
</div>
176+
}
177+
// placeholder={placeholder}
178+
ErrorBoundary={LexicalErrorBoundary}
179+
/>
162180
{/* </PhotoProvider> */}
163181
{/* {floatingAnchorElem && (
164182
<>
@@ -230,7 +248,7 @@ export default function Editor({ onChange, readOnly, toolbar, showLabel, copus =
230248
<PageBreakPlugin />
231249
<PayLinePlugin />
232250
<LayoutPlugin />
233-
{floatingAnchorElem && (
251+
{floatingAnchorElem && !isSmallWidthViewport && (
234252
<>
235253
<DraggableBlockPlugin anchorElem={floatingAnchorElem} />
236254
<CodeActionMenuPlugin anchorElem={floatingAnchorElem} />
@@ -240,11 +258,15 @@ export default function Editor({ onChange, readOnly, toolbar, showLabel, copus =
240258
setIsLinkEditMode={setIsLinkEditMode}
241259
/>
242260
<TableCellActionMenuPlugin anchorElem={floatingAnchorElem} cellMerge={true} />
243-
<FloatingCopusToolbarPlugin
244-
copus={copus}
261+
<FloatingTextFormatToolbarPlugin
245262
anchorElem={floatingAnchorElem}
246263
setIsLinkEditMode={setIsLinkEditMode}
247264
/>
265+
{/* <FloatingCopusToolbarPlugin
266+
copus={copus}
267+
anchorElem={floatingAnchorElem}
268+
setIsLinkEditMode={setIsLinkEditMode}
269+
/> */}
248270
{/* <CopusPlugin copus={copus} /> */}
249271
</>
250272
)}
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
*/
8+
9+
.floating-text-format-popup {
10+
display: flex;
11+
background: #fff;
12+
padding: 4px;
13+
vertical-align: middle;
14+
position: absolute;
15+
top: 0;
16+
left: 0;
17+
z-index: 10;
18+
opacity: 0;
19+
box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.3);
20+
border-radius: 8px;
21+
transition: opacity 0.5s;
22+
height: 35px;
23+
will-change: transform;
24+
}
25+
26+
.floating-text-format-popup button.popup-item {
27+
border: 0;
28+
display: flex;
29+
background: none;
30+
border-radius: 10px;
31+
padding: 8px;
32+
cursor: pointer;
33+
vertical-align: middle;
34+
}
35+
36+
.floating-text-format-popup button.popup-item:disabled {
37+
cursor: not-allowed;
38+
}
39+
40+
.floating-text-format-popup button.popup-item.spaced {
41+
margin-right: 2px;
42+
}
43+
44+
.floating-text-format-popup button.popup-item i.format {
45+
background-size: contain;
46+
height: 18px;
47+
width: 18px;
48+
margin-top: 2px;
49+
vertical-align: -0.25em;
50+
display: flex;
51+
opacity: 0.6;
52+
}
53+
54+
.floating-text-format-popup button.popup-item:disabled i.format {
55+
opacity: 0.2;
56+
}
57+
58+
.floating-text-format-popup button.popup-item.active {
59+
background-color: rgba(223, 232, 250, 0.3);
60+
}
61+
62+
.floating-text-format-popup button.popup-item.active i {
63+
opacity: 1;
64+
}
65+
66+
.floating-text-format-popup .popup-item:hover:not([disabled]) {
67+
background-color: #eee;
68+
}
69+
70+
.floating-text-format-popup select.popup-item {
71+
border: 0;
72+
display: flex;
73+
background: none;
74+
border-radius: 10px;
75+
padding: 8px;
76+
vertical-align: middle;
77+
-webkit-appearance: none;
78+
-moz-appearance: none;
79+
width: 70px;
80+
font-size: 14px;
81+
color: #777;
82+
text-overflow: ellipsis;
83+
}
84+
85+
.floating-text-format-popup select.code-language {
86+
text-transform: capitalize;
87+
width: 130px;
88+
}
89+
90+
.floating-text-format-popup .popup-item .text {
91+
display: flex;
92+
line-height: 20px;
93+
vertical-align: middle;
94+
font-size: 14px;
95+
color: #777;
96+
text-overflow: ellipsis;
97+
width: 70px;
98+
overflow: hidden;
99+
height: 20px;
100+
text-align: left;
101+
}
102+
103+
.floating-text-format-popup .popup-item .icon {
104+
display: flex;
105+
width: 20px;
106+
height: 20px;
107+
user-select: none;
108+
margin-right: 8px;
109+
line-height: 16px;
110+
background-size: contain;
111+
}
112+
113+
.floating-text-format-popup i.chevron-down {
114+
margin-top: 3px;
115+
width: 16px;
116+
height: 16px;
117+
display: flex;
118+
user-select: none;
119+
}
120+
121+
.floating-text-format-popup i.chevron-down.inside {
122+
width: 16px;
123+
height: 16px;
124+
display: flex;
125+
margin-left: -25px;
126+
margin-top: 11px;
127+
margin-right: 10px;
128+
pointer-events: none;
129+
}
130+
131+
.floating-text-format-popup .divider {
132+
width: 1px;
133+
background-color: #eee;
134+
margin: 0 4px;
135+
}
136+
137+
@media (max-width: 1024px) {
138+
.floating-text-format-popup button.insert-comment {
139+
display: none;
140+
}
141+
}

0 commit comments

Comments
 (0)