-
Notifications
You must be signed in to change notification settings - Fork 94
/
index.js
134 lines (120 loc) · 4.35 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import React, { useRef, useEffect } from 'react';
import PropTypes from 'prop-types';
import { ReactEditor, useEditor } from 'slate-react';
import { Transforms } from 'slate';
import { InsertTableButton } from 'plugins/withTables';
import { InsertImageButton } from '../plugins/withImages';
import ToolbarMenu from './ToolbarMenu';
import FormatButton from './FormatButton';
import InsertButton from './InsertButton';
import HistoryButton from './HistoryButton';
import HyperlinkButton from './HyperlinkButton';
import StyleDropdown from './StyleFormat';
import HyperlinkModal from './HyperlinkModal';
import TableModal from './TableModal';
import {
toggleBlock, isBlockActive,
toggleMark, isMarkActive,
toggleHistory, insertThematicBreak
} from '../utilities/toolbarHelpers';
import {
bold, italic, code,
quote, olist, ulist,
image, link, undo, redo,
tbreak, Separator, table
} from '../components/icons';
import DownloadDropdown from './DownloadDropdown';
const mark = { toggleFunc: toggleMark, activeFunc: isMarkActive };
const block = { toggleFunc: toggleBlock, activeFunc: isBlockActive };
const history = { toggleFunc: toggleHistory };
const insert = { toggleFunc: insertThematicBreak };
const FormattingToolbar = ({
canBeFormatted,
showLinkModal,
setShowLinkModal,
activeButton,
currentStyle,
showTableModal,
setShowTableModal
}) => {
const editor = useEditor();
const linkModalRef = useRef();
const tableModalRef = useRef();
const buttonProps = {
canBeFormatted,
activeButton
};
const linkProps = {
showLinkModal,
setShowLinkModal
};
const tableProps = {
showTableModal,
setShowTableModal
};
useEffect(() => {
if (showLinkModal || showTableModal) {
const el = showLinkModal ? linkModalRef.current : tableModalRef.current;
const domRange = ReactEditor.toDOMRange(editor, editor.selection);
const rect = domRange.getBoundingClientRect();
const CARET_TOP_OFFSET = 15;
el.style.opacity = 1;
el.style.top = `${
rect.top + rect.height + window.pageYOffset + CARET_TOP_OFFSET
}px`;
const hyperlinkCaret = el.children[0];
let calPos = rect.left - el.offsetWidth / 2;
// When the modal goes off page from left side
if (calPos < 0) {
// start from 10px
calPos = 10;
hyperlinkCaret.style.left = `${rect.left - 10}px`;
}
// calculate the endpoint of the modal
const rightEndPos = calPos + el.offsetWidth;
const containerWidth = el.parentElement.offsetWidth;
// When the modal goes off the page from right side
if (rightEndPos > containerWidth) {
let diff = rightEndPos - containerWidth;
// extra space of 10px on right side to look clean
diff += 10;
calPos -= diff;
const shift = diff - 5;
hyperlinkCaret.style.left = `calc(50% + ${shift}px)`;
}
el.style.left = `${calPos}px`;
}
}, [editor, showLinkModal, showTableModal]);
return (
<ToolbarMenu id="ap-rich-text-editor-toolbar">
<StyleDropdown canBeFormatted={canBeFormatted} currentStyle={currentStyle}/>
<Separator />
<FormatButton {...mark} {...bold} {...buttonProps} />
<FormatButton {...mark} {...italic} {...buttonProps} />
<FormatButton {...mark} {...code} {...buttonProps} />
<Separator />
<FormatButton {...block} {...quote} {...buttonProps} />
<FormatButton {...block} {...olist} {...buttonProps} />
<FormatButton {...block} {...ulist} {...buttonProps} />
<Separator />
<HistoryButton {...history} {...undo} />
<HistoryButton {...history} {...redo} />
<Separator />
<HyperlinkButton {...linkProps} {...link} {...buttonProps} />
<InsertImageButton {...image} canBeFormatted={canBeFormatted} />
<InsertButton {...insert} {...tbreak} canBeFormatted={canBeFormatted} />
<InsertTableButton {...table} {...tableProps} canBeFormatted={canBeFormatted} />
{ showLinkModal && <HyperlinkModal ref={linkModalRef} {...linkProps} /> }
{showTableModal && <TableModal ref={tableModalRef} {...tableProps} />}
<DownloadDropdown />
</ToolbarMenu>
);
};
FormattingToolbar.propTypes = {
canBeFormatted: PropTypes.func,
showLinkModal: PropTypes.bool,
setShowLinkModal: PropTypes.func,
activeButton: PropTypes.object,
currentStyle: PropTypes.string,
};
export default FormattingToolbar;