@zzish/math-rich-input 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +253 -0
- package/babel.config.js +6 -0
- package/dist/index.js +23034 -0
- package/dist/math-rich-input.css +923 -0
- package/package.json +44 -0
- package/rollup.config.js +31 -0
- package/src/AccentBar.css +169 -0
- package/src/AccentBar.jsx +771 -0
- package/src/EquationEditor.css +258 -0
- package/src/EquationEditor.jsx +583 -0
- package/src/EquationEditorModal.css +164 -0
- package/src/EquationEditorModal.jsx +81 -0
- package/src/MathRichArea.jsx +103 -0
- package/src/MathRichInput.css +63 -0
- package/src/MathRichInput.jsx +1651 -0
- package/src/SymbolButton.css +130 -0
- package/src/SymbolButton.jsx +96 -0
- package/src/Toolbar.css +142 -0
- package/src/Toolbar.jsx +219 -0
- package/src/equationEditorButtonsHelper.js +590 -0
- package/src/index.js +5 -0
- package/src/katexHelper.js +39 -0
- package/src/mathRichInputHelper.js +785 -0
- package/src/mimeTypeHelper.js +201 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/* Fixes is a katex bug where horizontal lines are not rendering */
|
|
2
|
+
/* .frac-line {
|
|
3
|
+
background-color: #404040;
|
|
4
|
+
height:0.03em;
|
|
5
|
+
}
|
|
6
|
+
.overline-line {
|
|
7
|
+
background-color: #404040;
|
|
8
|
+
height:0.03em;
|
|
9
|
+
} */
|
|
10
|
+
|
|
11
|
+
.SymbolButton {
|
|
12
|
+
overflow: hidden; /* Important to fix a bug where katex renders parts of the equation outside the box */
|
|
13
|
+
font-size: 14px;
|
|
14
|
+
font-weight: bold;
|
|
15
|
+
color: #202020;
|
|
16
|
+
background: #e0e0e0;
|
|
17
|
+
text-align: center;
|
|
18
|
+
border:0px;
|
|
19
|
+
border-radius: 5px;
|
|
20
|
+
width:36px;
|
|
21
|
+
height:36px;
|
|
22
|
+
padding:1px 1px 1px 1px;
|
|
23
|
+
margin:3px;
|
|
24
|
+
/* transition: all .2s ease-in-out; */
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
.SymbolButton:hover {
|
|
29
|
+
filter: saturate(2.0);
|
|
30
|
+
color: black;
|
|
31
|
+
/* transform: scale(1.3); */
|
|
32
|
+
cursor: pointer;
|
|
33
|
+
box-shadow: 1px 1px 3px #808080;
|
|
34
|
+
animation: 2s grow;
|
|
35
|
+
animation-fill-mode: forwards;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@keyframes grow {
|
|
39
|
+
00% {
|
|
40
|
+
transform: scale(1);
|
|
41
|
+
box-shadow: 0px 0px 0px #808080;
|
|
42
|
+
}
|
|
43
|
+
10% {
|
|
44
|
+
transform: scale(1.3);
|
|
45
|
+
box-shadow: 1px 1px 3px #808080;
|
|
46
|
+
}
|
|
47
|
+
90% {
|
|
48
|
+
transform: scale(1.3);
|
|
49
|
+
box-shadow: 1px 1px 3px #808080;
|
|
50
|
+
}
|
|
51
|
+
100% {
|
|
52
|
+
transform: scale(1.8);
|
|
53
|
+
box-shadow: 1px 1px 3px #808080;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.SymbolButton:active {
|
|
58
|
+
background: #808080;
|
|
59
|
+
color: white;
|
|
60
|
+
transform: scale(1.3);
|
|
61
|
+
cursor: pointer;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.SymbolButton-fadeIn {
|
|
65
|
+
opacity:1;
|
|
66
|
+
width:100px;
|
|
67
|
+
height:100px;
|
|
68
|
+
transition: width 0.5s, height 0.5s, opacity 0.5s 0.5s;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.highlight-0{
|
|
72
|
+
background: #ebc9eb;
|
|
73
|
+
/* background: #80e0e0; */
|
|
74
|
+
}
|
|
75
|
+
/*
|
|
76
|
+
.highlight-1{
|
|
77
|
+
background: #c0e0e0;
|
|
78
|
+
}
|
|
79
|
+
/* .highlight-2{
|
|
80
|
+
background: #c0e0e0;
|
|
81
|
+
} */
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
.highlight-operators{
|
|
85
|
+
background: #F8e8D8;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.highlight-angles{
|
|
89
|
+
background: #cceded;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.highlight-greeklower{
|
|
93
|
+
background: #F8e8D8;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.highlight-greekupper{
|
|
97
|
+
background: #cceded;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.highlight-misc{
|
|
101
|
+
background: #F8e8D8;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.highlight-sets{
|
|
105
|
+
background: #cceded;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.highlight-chemistry{
|
|
109
|
+
background: #F8e8D8;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.highlight-elements{
|
|
113
|
+
background: #cceded;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.highlight-physics2{
|
|
117
|
+
background: #F8e8D8;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.highlight-physics3{
|
|
121
|
+
background: #cceded;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.highlight-expert{
|
|
125
|
+
background: #f4d6f5;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.highlight-matrices{
|
|
129
|
+
background: #f4d6f5;
|
|
130
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
import katex from "katex";
|
|
4
|
+
|
|
5
|
+
import './SymbolButton.css';
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
getSymbolButtonLatex,
|
|
10
|
+
getSymbolButtonScaling,
|
|
11
|
+
// getSymbolButtonTooltip,
|
|
12
|
+
getSymbolButtonHtml,
|
|
13
|
+
setSymbolButtonHtml
|
|
14
|
+
} from './equationEditorButtonsHelper.js';
|
|
15
|
+
|
|
16
|
+
export default class SymbolButton extends React.Component {
|
|
17
|
+
|
|
18
|
+
// This is a fixed component that never changes
|
|
19
|
+
shouldComponentUpdate() {
|
|
20
|
+
if (this.props.shouldUpdate)
|
|
21
|
+
return this.props.shouldUpdate
|
|
22
|
+
return false
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
constructor(props) {
|
|
27
|
+
super(props);
|
|
28
|
+
this.suppliedClickHandler = null
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
static getButtonForDescendent(element) {
|
|
32
|
+
while (element && element.tagName.toLowerCase() !== "button")
|
|
33
|
+
element = element.parentNode;
|
|
34
|
+
return element
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
static getSymbolName(element) {
|
|
38
|
+
var button = SymbolButton.getButtonForDescendent(element)
|
|
39
|
+
if (button)
|
|
40
|
+
return button.getAttribute("name")
|
|
41
|
+
return null
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
handleSymbolButtonMouseDown = (event) => {
|
|
45
|
+
event.preventDefault()
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
handleSymbolButtonClick = (event) => {
|
|
49
|
+
this.suppliedClickHandler(event)
|
|
50
|
+
event.preventDefault()
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
render() {
|
|
54
|
+
// const {symbol} = this.props;
|
|
55
|
+
const {symbol, handleClick} = this.props;
|
|
56
|
+
this.suppliedClickHandler = handleClick
|
|
57
|
+
|
|
58
|
+
const fontSize = (14*getSymbolButtonScaling(symbol))/100
|
|
59
|
+
var buttonStyle = {fontSize: fontSize+'px'};
|
|
60
|
+
// const tooltipText = getSymbolButtonTooltip(symbol)
|
|
61
|
+
|
|
62
|
+
let katexHTML = getSymbolButtonHtml(symbol)
|
|
63
|
+
if (katexHTML === undefined || katexHTML === null) {
|
|
64
|
+
let latex = getSymbolButtonLatex(symbol)
|
|
65
|
+
katexHTML = katex.renderToString(latex)
|
|
66
|
+
|
|
67
|
+
// Not necessary, but lets clean out some unnessary mathml nodes
|
|
68
|
+
let start = katexHTML.indexOf("<span class=\"katex-mathml\">")
|
|
69
|
+
let end = -1
|
|
70
|
+
if (start > 0)
|
|
71
|
+
end = katexHTML.indexOf("</math></span>",start+30)
|
|
72
|
+
if (end > 0)
|
|
73
|
+
katexHTML = katexHTML.substring(0,start) + katexHTML.substring(end+14)
|
|
74
|
+
|
|
75
|
+
setSymbolButtonHtml(symbol, katexHTML)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
let useClassName = "SymbolButton"
|
|
79
|
+
if (this.props.highlight) {
|
|
80
|
+
useClassName = useClassName+" highlight-"+this.props.highlight
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return (
|
|
84
|
+
<span id='SymbolButton'>
|
|
85
|
+
<button name={symbol}
|
|
86
|
+
className={useClassName} style={buttonStyle}
|
|
87
|
+
onMouseDown={this.handleSymbolButtonMouseDown}
|
|
88
|
+
onClick={this.handleSymbolButtonClick}
|
|
89
|
+
ref={(e) => { this.button = e; }}>
|
|
90
|
+
<div name={symbol} dangerouslySetInnerHTML={{__html: katexHTML}} />
|
|
91
|
+
{/* <span className="tooltiptext">{tooltipText}</span> */}
|
|
92
|
+
</button>
|
|
93
|
+
</span>
|
|
94
|
+
)
|
|
95
|
+
}
|
|
96
|
+
}
|
package/src/Toolbar.css
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/* Note that the top left position of the toolbar is set programatically in componentDidMount */
|
|
2
|
+
|
|
3
|
+
.Toolbar {
|
|
4
|
+
position: fixed;
|
|
5
|
+
z-index: 1;
|
|
6
|
+
/* width:270px; */
|
|
7
|
+
height:42px;
|
|
8
|
+
background-color: white;
|
|
9
|
+
border: 1px solid #d0d0d0;
|
|
10
|
+
border-radius: 5px;
|
|
11
|
+
box-shadow: 1px 1px 5px #a0a0a0;
|
|
12
|
+
animation: 0.5s fadeIn1;
|
|
13
|
+
animation-fill-mode: forwards;
|
|
14
|
+
top: 0px;
|
|
15
|
+
left: 0px; /* important to set this so that toolbar initially renders full width */
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
@keyframes fadeIn1 {
|
|
19
|
+
0% {
|
|
20
|
+
opacity: 0;
|
|
21
|
+
}
|
|
22
|
+
100% {
|
|
23
|
+
opacity: 1.0;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.Toolbar-button {
|
|
28
|
+
font-family:sans-serif;
|
|
29
|
+
font-size: 16px;
|
|
30
|
+
width:40px;
|
|
31
|
+
height: 36px;
|
|
32
|
+
background-color: white;
|
|
33
|
+
border-radius: 5px;
|
|
34
|
+
border: 0px;
|
|
35
|
+
padding: 1px;
|
|
36
|
+
margin: 2px;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
.Toolbar-button:hover {
|
|
41
|
+
color: white;
|
|
42
|
+
background: #663676;
|
|
43
|
+
cursor: pointer;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.Toolbar-button:active {
|
|
47
|
+
background: #808080;
|
|
48
|
+
color: white;
|
|
49
|
+
cursor: pointer;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.TB-narrow {
|
|
53
|
+
width:30px;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.TB-wide {
|
|
57
|
+
width:46px;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.TB-up4 {
|
|
61
|
+
position: relative;
|
|
62
|
+
top:-4px;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.TB-selected {
|
|
66
|
+
background: #D0D0D0;
|
|
67
|
+
color: black;
|
|
68
|
+
cursor: pointer;
|
|
69
|
+
animation: 0.2s TB-fadeIn;
|
|
70
|
+
animation-fill-mode: forwards;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.TB-selected:hover {
|
|
74
|
+
color: white;
|
|
75
|
+
background: #663676;
|
|
76
|
+
cursor: pointer;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
@keyframes TB-fadeIn {
|
|
80
|
+
00% {
|
|
81
|
+
background: white;
|
|
82
|
+
}
|
|
83
|
+
100% {
|
|
84
|
+
background: #D0D0D0;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
/* Tooltip text */
|
|
90
|
+
.Toolbar-button .tooltiptext {
|
|
91
|
+
font-weight: normal;
|
|
92
|
+
visibility: hidden;
|
|
93
|
+
width: 100px;
|
|
94
|
+
background-color: #222;
|
|
95
|
+
color: #fff;
|
|
96
|
+
/*font-weight: bold;*/
|
|
97
|
+
font-size: 12px;
|
|
98
|
+
text-align: center;
|
|
99
|
+
padding: 4px 10px;
|
|
100
|
+
border-radius: 6px;
|
|
101
|
+
|
|
102
|
+
/* Position the tooltip text - see examples below! */
|
|
103
|
+
position: absolute;
|
|
104
|
+
z-index: 2;
|
|
105
|
+
top: -90%; /* Must leave a small gap between tooltip and button */
|
|
106
|
+
left: 50px;
|
|
107
|
+
|
|
108
|
+
/* transform: translate (50%,0%); */
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/* Show the tooltip text when you mouse over the tooltip container */
|
|
112
|
+
.Toolbar-button:hover .tooltiptext {
|
|
113
|
+
animation: 0.8s fadeIn2;
|
|
114
|
+
animation-fill-mode: forwards;
|
|
115
|
+
visibility: visible;
|
|
116
|
+
/* width: 100px; */
|
|
117
|
+
/* top: -90%; */ /* Must leave a small gap between tooltip and button */
|
|
118
|
+
/* left: 20%; */
|
|
119
|
+
/* margin-left: -50px; */
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
@keyframes fadeIn2 {
|
|
123
|
+
00% {
|
|
124
|
+
opacity: 0;
|
|
125
|
+
}
|
|
126
|
+
70% {
|
|
127
|
+
opacity: 0;
|
|
128
|
+
}
|
|
129
|
+
100% {
|
|
130
|
+
visibility: visible;
|
|
131
|
+
opacity: 0.9;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/* .tooltip {
|
|
136
|
+
position: relative;
|
|
137
|
+
display: inline-block;
|
|
138
|
+
border-bottom: 1px dotted black; /* If you want dots under the hoverable text
|
|
139
|
+
} */
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
|
package/src/Toolbar.jsx
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import katex from "katex";
|
|
3
|
+
|
|
4
|
+
import AccentBar from "./AccentBar";
|
|
5
|
+
|
|
6
|
+
import './Toolbar.css';
|
|
7
|
+
|
|
8
|
+
// const DEFAULT_TRANSLATE = 0
|
|
9
|
+
const DEFAULT_TOP = 0
|
|
10
|
+
const DEFAULT_LEFT = 0
|
|
11
|
+
const BOTTOM_MARGIN = 5
|
|
12
|
+
|
|
13
|
+
const CTRL_OR_META = /(Mac)/i.test(window.navigator.platform) ? "\u2318": "CTRL+"
|
|
14
|
+
|
|
15
|
+
export default class Toolbar extends React.Component {
|
|
16
|
+
constructor(props) {
|
|
17
|
+
super(props);
|
|
18
|
+
|
|
19
|
+
this.state = {
|
|
20
|
+
showAccents:false,
|
|
21
|
+
top:DEFAULT_TOP,
|
|
22
|
+
left:DEFAULT_LEFT
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
this.handleButtonClick = this.handleButtonClick.bind(this)
|
|
26
|
+
|
|
27
|
+
this.suppliedClickHandler = null
|
|
28
|
+
this.suppliedAccentLetterFetcher = null
|
|
29
|
+
this.suppliedAccentLetterReplacer = null
|
|
30
|
+
this.accentLetter = null
|
|
31
|
+
this.shouldUpdatePosition = true
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
handleButtonClick = (event, buttonName) => {
|
|
35
|
+
this.suppliedClickHandler(event, buttonName)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
showAccentBar = (event) => {
|
|
39
|
+
console.log("showAccentBar")
|
|
40
|
+
if (!this.state.showAccents)
|
|
41
|
+
this.accentLetter = this.suppliedAccentLetterFetcher()
|
|
42
|
+
this.setState({showAccents: true})
|
|
43
|
+
event.preventDefault()
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
hideAccentBar = (event) => {
|
|
47
|
+
console.log("hideAccentBar")
|
|
48
|
+
this.setState({showAccents: false})
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
showOrHideAccentBar = (event) => {
|
|
52
|
+
if (!this.state.showAccents)
|
|
53
|
+
this.accentLetter = this.suppliedAccentLetterFetcher()
|
|
54
|
+
this.setState({showAccents: !this.state.showAccents})
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
handleButtonClick = (event, buttonName) => {
|
|
58
|
+
this.suppliedClickHandler(event, buttonName)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
handleAccentButtonClick = (event, oldCharacter, newCharacter) => {
|
|
62
|
+
console.log("handleAccentButtonClick")
|
|
63
|
+
this.suppliedAccentLetterInserter(event, oldCharacter, newCharacter)
|
|
64
|
+
// this.hideAccentBar(null)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
componentDidMount() {
|
|
68
|
+
// We render once to find out the component's preferred size and then render again to update it
|
|
69
|
+
if (this.shouldUpdatePosition) {
|
|
70
|
+
// Lets position the accent bar below the input field and right aligned
|
|
71
|
+
let thisBar = this.toolbar
|
|
72
|
+
let node = thisBar.parentNode
|
|
73
|
+
while(node !== null && !node.classList.contains("MathRichInput-Container"))
|
|
74
|
+
node = node.parentNode
|
|
75
|
+
|
|
76
|
+
if (node === null) {
|
|
77
|
+
console.error("Could not find ancestor MathRichInput-Container find parent")
|
|
78
|
+
return
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
let inputBounds = node.getBoundingClientRect()
|
|
82
|
+
let thisBounds = thisBar.getBoundingClientRect()
|
|
83
|
+
|
|
84
|
+
this.shouldUpdatePosition = false
|
|
85
|
+
|
|
86
|
+
// Vertically align above input field
|
|
87
|
+
let top = inputBounds.top - thisBounds.height - BOTTOM_MARGIN
|
|
88
|
+
|
|
89
|
+
// Horizontally align to right of input field
|
|
90
|
+
let left = inputBounds.right - thisBounds.width
|
|
91
|
+
|
|
92
|
+
// Make sure it is on screen horizontally
|
|
93
|
+
if (thisBounds.width > inputBounds.width)
|
|
94
|
+
left = inputBounds.left - (thisBounds.width - inputBounds.width)/2
|
|
95
|
+
|
|
96
|
+
if (left + thisBounds.width > window.innerWidth)
|
|
97
|
+
left = window.innerWidth - thisBounds.width - 2
|
|
98
|
+
|
|
99
|
+
if (left < 0)
|
|
100
|
+
left = 0
|
|
101
|
+
|
|
102
|
+
this.setState({left, top})
|
|
103
|
+
|
|
104
|
+
} else {
|
|
105
|
+
this.shouldUpdatePosition = true
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
render() {
|
|
110
|
+
console.log("Rendering toolbar")
|
|
111
|
+
this.suppliedClickHandler = this.props.onButtonClick
|
|
112
|
+
this.suppliedAccentLetterFetcher = this.props.fetchAccentLetter
|
|
113
|
+
this.suppliedAccentLetterInserter = this.props.insertAccentLetter
|
|
114
|
+
|
|
115
|
+
let enableFontStyling = this.props.enableFontStyling ?? true
|
|
116
|
+
let enableMath = this.props.enableMath ?? true
|
|
117
|
+
|
|
118
|
+
let katexHTML = katex.renderToString("f(x)")
|
|
119
|
+
// Not really necessary, but lets clean out some unnessary mathml nodes
|
|
120
|
+
let start = katexHTML.indexOf("<span class=\"katex-mathml\">")
|
|
121
|
+
let end = -1
|
|
122
|
+
if (start > 0)
|
|
123
|
+
end = katexHTML.indexOf("</math></span>",start+30)
|
|
124
|
+
if (end > 0)
|
|
125
|
+
katexHTML = katexHTML.substring(0,start) + katexHTML.substring(end+14)
|
|
126
|
+
|
|
127
|
+
// Set up the tranlation to place the toolbar where we want it
|
|
128
|
+
let style = {...this.props.style}
|
|
129
|
+
// if (this.state.translateX !== DEFAULT_TRANSLATE) {
|
|
130
|
+
// style.transform = "translate("+this.state.translateX+"px, "+this.state.translateY+"px)";
|
|
131
|
+
// }
|
|
132
|
+
if (this.state.left !== DEFAULT_LEFT || this.state.top !== DEFAULT_TOP) {
|
|
133
|
+
style.left = this.state.left + "px"
|
|
134
|
+
style.top = this.state.top + "px"
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return (
|
|
138
|
+
<div
|
|
139
|
+
className='Toolbar'
|
|
140
|
+
style={style}
|
|
141
|
+
ref={(r) => this.toolbar = r}
|
|
142
|
+
>
|
|
143
|
+
{enableFontStyling &&
|
|
144
|
+
<>
|
|
145
|
+
<button name="Bold"
|
|
146
|
+
className={"Toolbar-button TB-narrow" +
|
|
147
|
+
(this.props.activeButtons.bold ? " TB-selected" : "")}
|
|
148
|
+
onClick={(e) => e.preventDefault()}
|
|
149
|
+
onMouseDown={(e) => e.preventDefault()}
|
|
150
|
+
onMouseUp={(e) => this.handleButtonClick(e, "Bold")}>
|
|
151
|
+
<b>B</b>
|
|
152
|
+
</button>
|
|
153
|
+
|
|
154
|
+
<button name="Italic"
|
|
155
|
+
className={"Toolbar-button TB-narrow" +
|
|
156
|
+
(this.props.activeButtons.italic ? " TB-selected" : "")}
|
|
157
|
+
onClick={(e) => e.preventDefault()}
|
|
158
|
+
onMouseDown={(e) => e.preventDefault()}
|
|
159
|
+
onMouseUp={(e) => this.handleButtonClick(e, "Italic")}>
|
|
160
|
+
<i>I</i>
|
|
161
|
+
</button>
|
|
162
|
+
|
|
163
|
+
<button name="Underline"
|
|
164
|
+
className={"Toolbar-button TB-narrow" +
|
|
165
|
+
(this.props.activeButtons.underline ? " TB-selected" : "")}
|
|
166
|
+
onClick={(e) => e.preventDefault()}
|
|
167
|
+
onMouseDown={(e) => e.preventDefault()}
|
|
168
|
+
onMouseUp={(e) => this.handleButtonClick(e, "Underline")}>
|
|
169
|
+
<u>U</u>
|
|
170
|
+
</button>
|
|
171
|
+
|
|
172
|
+
<button name="Superscript"
|
|
173
|
+
className={"Toolbar-button TB-narrow" +
|
|
174
|
+
(this.props.activeButtons.superscript ? " TB-selected" : "")}
|
|
175
|
+
onClick={(e) => e.preventDefault()}
|
|
176
|
+
onMouseDown={(e) => e.preventDefault()}
|
|
177
|
+
onMouseUp={(e) => this.handleButtonClick(e, "Superscript")}>
|
|
178
|
+
a<sup>x</sup>
|
|
179
|
+
</button>
|
|
180
|
+
|
|
181
|
+
<button name="Subscript"
|
|
182
|
+
className={"Toolbar-button TB-narrow TB-up4" +
|
|
183
|
+
(this.props.activeButtons.subscript ? " TB-selected" : "")}
|
|
184
|
+
onClick={(e) => e.preventDefault()}
|
|
185
|
+
onMouseDown={(e) => e.preventDefault()}
|
|
186
|
+
onMouseUp={(e) => this.handleButtonClick(e, "Subscript")}>
|
|
187
|
+
a<sub>x</sub>
|
|
188
|
+
</button>
|
|
189
|
+
</>}
|
|
190
|
+
|
|
191
|
+
<button name="Accents"
|
|
192
|
+
className={"Toolbar-button TB-narrow" +
|
|
193
|
+
(this.state.showAccents ? " TB-selected" : "")}
|
|
194
|
+
onMouseDown={(e) => e.preventDefault()}
|
|
195
|
+
onClick={(e) => e.preventDefault()}
|
|
196
|
+
onMouseUp={(e) => this.showOrHideAccentBar(e)}>
|
|
197
|
+
á
|
|
198
|
+
</button>
|
|
199
|
+
|
|
200
|
+
{enableMath &&
|
|
201
|
+
<button name="Equation"
|
|
202
|
+
className="Toolbar-button TB-wide" onMouseDown={(e) => this.handleButtonClick(e, "Equation")}>
|
|
203
|
+
<div dangerouslySetInnerHTML={{__html: katexHTML}} />
|
|
204
|
+
<span className="tooltiptext">Insert equation [{CTRL_OR_META}Enter]</span>
|
|
205
|
+
</button>
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
{this.state.showAccents &&
|
|
209
|
+
<AccentBar
|
|
210
|
+
accentLetter={this.accentLetter}
|
|
211
|
+
keyPressed={this.props.keyPressed}
|
|
212
|
+
fetchAccentLetter={this.props.fetchAccentLetter}
|
|
213
|
+
onButtonClick={(e, oldCharacter, newCharacter) =>
|
|
214
|
+
this.handleAccentButtonClick(e, oldCharacter, newCharacter)}/>
|
|
215
|
+
}
|
|
216
|
+
</div>
|
|
217
|
+
)
|
|
218
|
+
}
|
|
219
|
+
}
|