@pie-lib/math-input 6.11.5-next.0 → 6.11.5-next.1844
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/CHANGELOG.json +6 -1536
- package/CHANGELOG.md +178 -117
- package/NEXT.CHANGELOG.json +1 -0
- package/lib/horizontal-keypad.js +9 -3
- package/lib/horizontal-keypad.js.map +1 -1
- package/lib/index.js +10 -14
- package/lib/index.js.map +1 -1
- package/lib/keypad/index.js +95 -24
- package/lib/keypad/index.js.map +1 -1
- package/lib/keys/geometry.js +4 -2
- package/lib/keys/geometry.js.map +1 -1
- package/lib/keys/grades.js +12 -0
- package/lib/keys/grades.js.map +1 -1
- package/lib/keys/log.js +1 -1
- package/lib/keys/log.js.map +1 -1
- package/lib/mq/common-mq-styles.js +110 -0
- package/lib/mq/common-mq-styles.js.map +1 -0
- package/lib/mq/index.js +8 -0
- package/lib/mq/index.js.map +1 -1
- package/lib/mq/input.js +12 -10
- package/lib/mq/input.js.map +1 -1
- package/lib/mq/static.js +198 -75
- package/lib/mq/static.js.map +1 -1
- package/lib/shared/constants.js +16 -0
- package/lib/updateSpans.js +23 -0
- package/lib/updateSpans.js.map +1 -0
- package/package.json +4 -2
- package/src/__tests__/__snapshots__/math-input-test.jsx.snap +152 -0
- package/src/__tests__/math-input-test.jsx +85 -0
- package/src/horizontal-keypad.jsx +14 -1
- package/src/index.jsx +1 -10
- package/src/keypad/__tests__/__snapshots__/index.test.jsx.snap +193 -0
- package/src/keypad/__tests__/index.test.jsx +24 -0
- package/src/keypad/__tests__/keys-layout.test.js +15 -0
- package/src/keypad/index.jsx +99 -15
- package/src/keys/__tests__/utils.test.js +57 -0
- package/src/keys/geometry.js +6 -2
- package/src/keys/grades.js +11 -0
- package/src/keys/log.js +1 -1
- package/src/mq/__tests__/__snapshots__/input.test.jsx.snap +9 -0
- package/src/mq/__tests__/input.test.jsx +92 -0
- package/src/mq/__tests__/static.test.jsx +57 -0
- package/src/mq/common-mq-styles.js +105 -0
- package/src/mq/index.js +2 -1
- package/src/mq/input.jsx +22 -9
- package/src/mq/static.jsx +142 -13
- package/src/updateSpans.js +15 -0
- package/README.md +0 -27
package/src/mq/input.jsx
CHANGED
|
@@ -53,14 +53,17 @@ export class Input extends React.Component {
|
|
|
53
53
|
if (!this.mathField) {
|
|
54
54
|
return;
|
|
55
55
|
}
|
|
56
|
+
|
|
56
57
|
const { latex } = this.props;
|
|
57
|
-
|
|
58
|
+
|
|
59
|
+
if (latex !== undefined && latex !== null) {
|
|
58
60
|
this.mathField.latex(latex);
|
|
59
61
|
}
|
|
60
62
|
}
|
|
61
63
|
|
|
62
64
|
clear() {
|
|
63
65
|
this.mathField.latex('');
|
|
66
|
+
|
|
64
67
|
return '';
|
|
65
68
|
}
|
|
66
69
|
|
|
@@ -83,13 +86,16 @@ export class Input extends React.Component {
|
|
|
83
86
|
} else {
|
|
84
87
|
this.mathField.cmd(v);
|
|
85
88
|
}
|
|
89
|
+
|
|
86
90
|
this.mathField.focus();
|
|
91
|
+
|
|
87
92
|
return this.mathField.latex();
|
|
88
93
|
}
|
|
89
94
|
|
|
90
95
|
keystroke(v) {
|
|
91
96
|
this.mathField.keystroke(v);
|
|
92
97
|
this.mathField.focus();
|
|
98
|
+
|
|
93
99
|
return this.mathField.latex();
|
|
94
100
|
}
|
|
95
101
|
|
|
@@ -97,12 +103,14 @@ export class Input extends React.Component {
|
|
|
97
103
|
log('write: ', v);
|
|
98
104
|
this.mathField.write(v);
|
|
99
105
|
this.mathField.focus();
|
|
106
|
+
|
|
100
107
|
return this.mathField.latex();
|
|
101
108
|
}
|
|
102
109
|
|
|
103
110
|
onInputEdit = () => {
|
|
104
111
|
log('[onInputEdit] ...');
|
|
105
112
|
const { onChange } = this.props;
|
|
113
|
+
|
|
106
114
|
if (!this.mathField) {
|
|
107
115
|
return;
|
|
108
116
|
}
|
|
@@ -128,28 +136,33 @@ export class Input extends React.Component {
|
|
|
128
136
|
}
|
|
129
137
|
|
|
130
138
|
if (event.charCode === 13) {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
// all because mathquill doesn't support a line break
|
|
134
|
-
this.write('\\embed{newLine}[]');
|
|
135
|
-
this.onInputEdit();
|
|
139
|
+
event.preventDefault();
|
|
140
|
+
return;
|
|
136
141
|
}
|
|
137
142
|
};
|
|
138
143
|
|
|
144
|
+
onClick = (event) => {
|
|
145
|
+
const { onClick } = this.props;
|
|
146
|
+
|
|
147
|
+
this.refresh();
|
|
148
|
+
onClick && onClick(event);
|
|
149
|
+
};
|
|
150
|
+
|
|
139
151
|
shouldComponentUpdate(nextProps) {
|
|
140
152
|
log('next: ', nextProps.latex);
|
|
141
153
|
log('current: ', this.mathField.latex());
|
|
154
|
+
|
|
142
155
|
return nextProps.latex !== this.mathField.latex();
|
|
143
156
|
}
|
|
144
157
|
|
|
145
158
|
render() {
|
|
146
|
-
const {
|
|
159
|
+
const { onFocus, onBlur, classes, className } = this.props;
|
|
147
160
|
|
|
148
161
|
return (
|
|
149
162
|
<span
|
|
150
163
|
className={classNames(classes.input, className)}
|
|
151
|
-
|
|
152
|
-
onClick={onClick}
|
|
164
|
+
onKeyDown={this.onKeyPress}
|
|
165
|
+
onClick={this.onClick}
|
|
153
166
|
onFocus={onFocus}
|
|
154
167
|
onBlur={onBlur}
|
|
155
168
|
ref={(r) => (this.input = r)}
|
package/src/mq/static.jsx
CHANGED
|
@@ -2,7 +2,7 @@ import PropTypes from 'prop-types';
|
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import debug from 'debug';
|
|
4
4
|
import MathQuill from '@pie-framework/mathquill';
|
|
5
|
-
import { updateSpans } from '../
|
|
5
|
+
import { updateSpans } from '../updateSpans';
|
|
6
6
|
|
|
7
7
|
let MQ;
|
|
8
8
|
if (typeof window !== 'undefined') {
|
|
@@ -17,6 +17,18 @@ function stripSpaces(string = '') {
|
|
|
17
17
|
return string.replace(WHITESPACE_REGEX, '');
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
function countBraces(latex) {
|
|
21
|
+
let count = 0;
|
|
22
|
+
|
|
23
|
+
for (let i = 0; i < (latex || '').length; i++) {
|
|
24
|
+
if (latex[i] === '{') {
|
|
25
|
+
count++;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return count;
|
|
30
|
+
}
|
|
31
|
+
|
|
20
32
|
/**
|
|
21
33
|
* Wrapper for MathQuill MQ.MathField.
|
|
22
34
|
*/
|
|
@@ -36,9 +48,24 @@ export default class Static extends React.Component {
|
|
|
36
48
|
getFieldName: () => {},
|
|
37
49
|
};
|
|
38
50
|
|
|
51
|
+
constructor(props) {
|
|
52
|
+
super(props);
|
|
53
|
+
this.state = {
|
|
54
|
+
announcement: '',
|
|
55
|
+
previousLatex: '',
|
|
56
|
+
inputSource: null,
|
|
57
|
+
isDeleteKeyPressed: false,
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
this.inputRef = React.createRef();
|
|
61
|
+
}
|
|
62
|
+
|
|
39
63
|
componentDidMount() {
|
|
40
64
|
this.update();
|
|
41
65
|
updateSpans();
|
|
66
|
+
|
|
67
|
+
this.createLiveRegion();
|
|
68
|
+
this.addEventListeners();
|
|
42
69
|
}
|
|
43
70
|
|
|
44
71
|
componentDidUpdate() {
|
|
@@ -46,7 +73,62 @@ export default class Static extends React.Component {
|
|
|
46
73
|
updateSpans();
|
|
47
74
|
}
|
|
48
75
|
|
|
49
|
-
|
|
76
|
+
componentWillUnmount() {
|
|
77
|
+
this.removeLiveRegion();
|
|
78
|
+
this.removeEventListeners();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
createLiveRegion = () => {
|
|
82
|
+
this.liveRegion = document.createElement('div');
|
|
83
|
+
this.liveRegion.style.position = 'absolute';
|
|
84
|
+
this.liveRegion.style.width = '1px';
|
|
85
|
+
this.liveRegion.style.height = '1px';
|
|
86
|
+
this.liveRegion.style.marginTop = '-1px';
|
|
87
|
+
this.liveRegion.style.clip = 'rect(1px, 1px, 1px, 1px)';
|
|
88
|
+
this.liveRegion.style.overflow = 'hidden';
|
|
89
|
+
this.liveRegion.setAttribute('aria-live', 'polite');
|
|
90
|
+
this.liveRegion.setAttribute('aria-atomic', 'true');
|
|
91
|
+
|
|
92
|
+
document.body.appendChild(this.liveRegion);
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
addEventListeners = () => {
|
|
96
|
+
const input = this.inputRef.current;
|
|
97
|
+
|
|
98
|
+
if (input) {
|
|
99
|
+
input.addEventListener('keydown', this.handleKeyDown);
|
|
100
|
+
input.addEventListener('click', this.handleMathKeyboardClick);
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
removeEventListeners = () => {
|
|
105
|
+
const input = this.inputRef.current;
|
|
106
|
+
|
|
107
|
+
if (input) {
|
|
108
|
+
input.removeEventListener('keydown', this.handleKeyDown);
|
|
109
|
+
input.removeEventListener('click', this.handleMathKeyboardClick);
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
removeLiveRegion = () => {
|
|
114
|
+
if (this.liveRegion) {
|
|
115
|
+
document.body.removeChild(this.liveRegion);
|
|
116
|
+
this.liveRegion = null;
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
handleKeyDown = (event) => {
|
|
121
|
+
if (event?.key === 'Backspace' || event?.key === 'Delete') {
|
|
122
|
+
this.setState({ isDeleteKeyPressed: true });
|
|
123
|
+
}
|
|
124
|
+
this.setState({ inputSource: 'keyboard' });
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
handleMathKeyboardClick = () => {
|
|
128
|
+
this.setState({ inputSource: 'mathKeyboard' });
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
onInputEdit = (field) => {
|
|
50
132
|
if (!this.mathField) {
|
|
51
133
|
return;
|
|
52
134
|
}
|
|
@@ -56,7 +138,7 @@ export default class Static extends React.Component {
|
|
|
56
138
|
// eslint-disable-next-line no-useless-escape
|
|
57
139
|
const regexMatch = field.latex().match(/[0-9]\\ \\frac\{[^\{]*\}\{ \}/);
|
|
58
140
|
|
|
59
|
-
if (this.
|
|
141
|
+
if (this.inputRef?.current && regexMatch && regexMatch?.length) {
|
|
60
142
|
try {
|
|
61
143
|
field.__controller.cursor.insLeftOf(field.__controller.cursor.parent[-1].parent);
|
|
62
144
|
field.el().dispatchEvent(new KeyboardEvent('keydown', { keyCode: 8 }));
|
|
@@ -68,15 +150,62 @@ export default class Static extends React.Component {
|
|
|
68
150
|
this.props.onSubFieldChange(name, field.latex());
|
|
69
151
|
}
|
|
70
152
|
}
|
|
71
|
-
}
|
|
72
153
|
|
|
73
|
-
|
|
154
|
+
this.announceLatexConversion(field.latex());
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
announceLatexConversion = (newLatex) => {
|
|
158
|
+
if (!this.state) {
|
|
159
|
+
console.error('State is not initialized');
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const { previousLatex, inputSource, isDeleteKeyPressed } = this.state;
|
|
164
|
+
const announcement = 'Converted to math symbol';
|
|
165
|
+
|
|
166
|
+
if (inputSource === 'keyboard' && !isDeleteKeyPressed) {
|
|
167
|
+
const newBraces = countBraces(newLatex);
|
|
168
|
+
const oldBraces = countBraces(previousLatex);
|
|
169
|
+
|
|
170
|
+
if (newBraces > oldBraces) {
|
|
171
|
+
this.announceMessage(announcement);
|
|
172
|
+
} else {
|
|
173
|
+
try {
|
|
174
|
+
this.mathField.parseLatex(previousLatex);
|
|
175
|
+
this.mathField.parseLatex(newLatex);
|
|
176
|
+
|
|
177
|
+
if (newLatex == previousLatex) {
|
|
178
|
+
this.announceMessage(announcement);
|
|
179
|
+
}
|
|
180
|
+
} catch (e) {
|
|
181
|
+
console.warn('Error parsing latex:', e.message);
|
|
182
|
+
console.warn(e);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
this.setState({ previousLatex: newLatex, isDeleteKeyPressed: false });
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
announceMessage = (message) => {
|
|
191
|
+
this.setState({ previousLatex: '' });
|
|
192
|
+
|
|
193
|
+
if (this.liveRegion) {
|
|
194
|
+
this.liveRegion.textContent = message;
|
|
195
|
+
|
|
196
|
+
// Clear the message after it is announced
|
|
197
|
+
setTimeout(() => {
|
|
198
|
+
this.liveRegion.textContent = '';
|
|
199
|
+
}, 500);
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
update = () => {
|
|
74
204
|
if (!MQ) {
|
|
75
205
|
throw new Error('MQ is not defined - but component has mounted?');
|
|
76
206
|
}
|
|
77
|
-
// this.input.innerHTML = this.props.latex;
|
|
78
207
|
if (!this.mathField) {
|
|
79
|
-
this.mathField = MQ.StaticMath(this.
|
|
208
|
+
this.mathField = MQ.StaticMath(this.inputRef?.current, {
|
|
80
209
|
handlers: {
|
|
81
210
|
edit: this.onInputEdit.bind(this),
|
|
82
211
|
},
|
|
@@ -90,17 +219,17 @@ export default class Static extends React.Component {
|
|
|
90
219
|
// default latex if received has errors
|
|
91
220
|
this.mathField.latex('\\MathQuillMathField[r1]{}');
|
|
92
221
|
}
|
|
93
|
-
}
|
|
222
|
+
};
|
|
94
223
|
|
|
95
|
-
blur() {
|
|
224
|
+
blur = () => {
|
|
96
225
|
log('blur mathfield');
|
|
97
226
|
this.mathField.blur();
|
|
98
|
-
}
|
|
227
|
+
};
|
|
99
228
|
|
|
100
|
-
focus() {
|
|
229
|
+
focus = () => {
|
|
101
230
|
log('focus mathfield...');
|
|
102
231
|
this.mathField.focus();
|
|
103
|
-
}
|
|
232
|
+
};
|
|
104
233
|
|
|
105
234
|
shouldComponentUpdate(nextProps) {
|
|
106
235
|
try {
|
|
@@ -151,6 +280,6 @@ export default class Static extends React.Component {
|
|
|
151
280
|
render() {
|
|
152
281
|
const { onBlur, className } = this.props;
|
|
153
282
|
|
|
154
|
-
return <span className={className} onFocus={this.onFocus} onBlur={onBlur} ref={
|
|
283
|
+
return <span className={className} onFocus={this.onFocus} onBlur={onBlur} ref={this.inputRef} />;
|
|
155
284
|
}
|
|
156
285
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// increase the font of parallel notation
|
|
2
|
+
const updateSpans = () => {
|
|
3
|
+
const spans = Array.from(document.querySelectorAll('span[mathquill-command-id]'));
|
|
4
|
+
(spans || []).forEach((span) => {
|
|
5
|
+
if (span && span.innerText === '∥' && span.className !== 'mq-editable-field') {
|
|
6
|
+
span.style.fontSize = '32px';
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
if ((span.innerText === '′' || span.innerText === '′′') && !span.hasAttribute('data-prime')) {
|
|
10
|
+
span.setAttribute('data-prime', 'true');
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export { updateSpans };
|
package/README.md
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
# math-input
|
|
2
|
-
|
|
3
|
-
A [React](http://github.com/facebook/react) math input field, with a material design feel. Uses [Mathquill](http://mathquill.com/).
|
|
4
|
-
|
|
5
|
-
## install
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npm|yarn install
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## demo
|
|
12
|
-
```bash
|
|
13
|
-
|
|
14
|
-
cd demo
|
|
15
|
-
../node_modules/.bin/webpack-dev-server --hot --inline
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
## test
|
|
19
|
-
|
|
20
|
-
```bash
|
|
21
|
-
npm|yarn test
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
## Using in another app
|
|
26
|
-
|
|
27
|
-
We expose the jsx directly, so you'll need to update your build pipeline to build from src.
|