@pie-lib/math-input-mathlive 1.1.5-beta.9 → 2.0.1-next.20261107131445
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 +84 -109
- package/dist/_virtual/_rolldown/runtime.js +11 -0
- package/dist/horizontal-keypad.d.ts +22 -0
- package/dist/horizontal-keypad.js +54 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +12 -0
- package/dist/keypad/index.d.ts +40 -0
- package/dist/keypad/index.js +245 -0
- package/dist/keypad/keys-layout.d.ts +7 -0
- package/dist/keypad/keys-layout.js +5 -0
- package/dist/keys/basic-operators.d.ts +5 -0
- package/dist/keys/basic-operators.js +30 -0
- package/dist/keys/chars.d.ts +5 -0
- package/dist/keys/comparison.d.ts +4 -0
- package/dist/keys/comparison.js +32 -0
- package/dist/keys/constants.d.ts +4 -0
- package/dist/keys/constants.js +35 -0
- package/dist/keys/digits.d.ts +15 -0
- package/dist/keys/digits.js +34 -0
- package/dist/keys/edit.d.ts +6 -0
- package/dist/keys/edit.js +9 -0
- package/dist/keys/exponent.d.ts +4 -0
- package/dist/keys/exponent.js +28 -0
- package/dist/keys/fractions.d.ts +3 -0
- package/dist/keys/fractions.js +27 -0
- package/dist/keys/geometry.d.ts +23 -0
- package/dist/keys/geometry.js +127 -0
- package/dist/keys/grades.d.ts +9 -0
- package/dist/keys/grades.js +414 -0
- package/dist/keys/index.d.ts +6 -0
- package/dist/keys/index.js +50 -0
- package/dist/keys/log.d.ts +3 -0
- package/dist/keys/log.js +25 -0
- package/dist/keys/logic.d.ts +2 -0
- package/dist/keys/logic.js +13 -0
- package/dist/keys/matrices.d.ts +2 -0
- package/dist/keys/matrices.js +17 -0
- package/dist/keys/misc.d.ts +10 -0
- package/dist/keys/misc.js +60 -0
- package/dist/keys/navigation.d.ts +2 -0
- package/dist/keys/navigation.js +13 -0
- package/dist/keys/operators.d.ts +1 -0
- package/dist/keys/operators.js +11 -0
- package/dist/keys/statistics.d.ts +5 -0
- package/dist/keys/statistics.js +38 -0
- package/dist/keys/sub-sup.d.ts +2 -0
- package/dist/keys/sub-sup.js +17 -0
- package/dist/keys/trigonometry.d.ts +6 -0
- package/dist/keys/trigonometry.js +43 -0
- package/dist/keys/utils.d.ts +5 -0
- package/dist/keys/utils.js +24 -0
- package/dist/keys/vars.d.ts +3 -0
- package/dist/keys/vars.js +22 -0
- package/dist/latex-bridge.d.ts +197 -0
- package/dist/latex-bridge.js +210 -0
- package/dist/longdiv.d.ts +24 -0
- package/dist/longdiv.js +43 -0
- package/dist/math-input.d.ts +26 -0
- package/dist/math-input.js +74 -0
- package/dist/mathlive-instance.d.ts +221 -0
- package/dist/mathlive-instance.js +159 -0
- package/dist/mf/common-styles.d.ts +594 -0
- package/dist/mf/common-styles.js +80 -0
- package/dist/mf/field-label.d.ts +16 -0
- package/dist/mf/field-label.js +13 -0
- package/dist/mf/index.d.ts +4 -0
- package/dist/mf/index.js +21 -0
- package/dist/mf/input.d.ts +94 -0
- package/dist/mf/input.js +127 -0
- package/dist/mf/static.d.ts +143 -0
- package/dist/mf/static.js +230 -0
- package/dist/selection.d.ts +43 -0
- package/dist/selection.js +39 -0
- package/package.json +32 -18
- package/lib/__tests__/composites.test.js +0 -255
- package/lib/__tests__/drop-in-compat.test.js +0 -133
- package/lib/__tests__/embedded-fonts.test.js +0 -121
- package/lib/__tests__/index.test.js +0 -118
- package/lib/__tests__/input-imperative.test.js +0 -155
- package/lib/__tests__/keypad-label.test.js +0 -231
- package/lib/__tests__/keypad-render.test.js +0 -206
- package/lib/__tests__/latex-bridge.test.js +0 -386
- package/lib/__tests__/mathlive-instance.test.js +0 -419
- package/lib/__tests__/mount-race.test.js +0 -218
- package/lib/__tests__/static-prompts.test.js +0 -405
- package/lib/__tests__/tmp-markup.test.js +0 -26
- package/lib/horizontal-keypad.js +0 -101
- package/lib/horizontal-keypad.js.map +0 -1
- package/lib/index.js +0 -143
- package/lib/index.js.map +0 -1
- package/lib/keypad/index.js +0 -431
- package/lib/keypad/index.js.map +0 -1
- package/lib/keypad/keys-layout.js +0 -22
- package/lib/keypad/keys-layout.js.map +0 -1
- package/lib/keys/basic-operators.js +0 -33
- package/lib/keys/basic-operators.js.map +0 -1
- package/lib/keys/chars.js +0 -12
- package/lib/keys/chars.js.map +0 -1
- package/lib/keys/comparison.js +0 -39
- package/lib/keys/comparison.js.map +0 -1
- package/lib/keys/constants.js +0 -37
- package/lib/keys/constants.js.map +0 -1
- package/lib/keys/digits.js +0 -46
- package/lib/keys/digits.js.map +0 -1
- package/lib/keys/edit.js +0 -14
- package/lib/keys/edit.js.map +0 -1
- package/lib/keys/exponent.js +0 -30
- package/lib/keys/exponent.js.map +0 -1
- package/lib/keys/fractions.js +0 -29
- package/lib/keys/fractions.js.map +0 -1
- package/lib/keys/geometry.js +0 -143
- package/lib/keys/geometry.js.map +0 -1
- package/lib/keys/grades.js +0 -259
- package/lib/keys/grades.js.map +0 -1
- package/lib/keys/index.js +0 -35
- package/lib/keys/index.js.map +0 -1
- package/lib/keys/log.js +0 -27
- package/lib/keys/log.js.map +0 -1
- package/lib/keys/logic.js +0 -19
- package/lib/keys/logic.js.map +0 -1
- package/lib/keys/matrices.js +0 -19
- package/lib/keys/matrices.js.map +0 -1
- package/lib/keys/misc.js +0 -69
- package/lib/keys/misc.js.map +0 -1
- package/lib/keys/navigation.js +0 -20
- package/lib/keys/navigation.js.map +0 -1
- package/lib/keys/operators.js +0 -15
- package/lib/keys/operators.js.map +0 -1
- package/lib/keys/statistics.js +0 -40
- package/lib/keys/statistics.js.map +0 -1
- package/lib/keys/sub-sup.js +0 -19
- package/lib/keys/sub-sup.js.map +0 -1
- package/lib/keys/trigonometry.js +0 -45
- package/lib/keys/trigonometry.js.map +0 -1
- package/lib/keys/utils.js +0 -87
- package/lib/keys/utils.js.map +0 -1
- package/lib/keys/vars.js +0 -24
- package/lib/keys/vars.js.map +0 -1
- package/lib/latex-bridge.js +0 -508
- package/lib/latex-bridge.js.map +0 -1
- package/lib/math-input.js +0 -143
- package/lib/math-input.js.map +0 -1
- package/lib/mathlive-instance.js +0 -585
- package/lib/mathlive-instance.js.map +0 -1
- package/lib/mf/common-styles.js +0 -203
- package/lib/mf/common-styles.js.map +0 -1
- package/lib/mf/index.js +0 -84
- package/lib/mf/index.js.map +0 -1
- package/lib/mf/input.js +0 -364
- package/lib/mf/input.js.map +0 -1
- package/lib/mf/static.js +0 -500
- package/lib/mf/static.js.map +0 -1
- package/src/__tests__/composites.test.jsx +0 -220
- package/src/__tests__/drop-in-compat.test.jsx +0 -112
- package/src/__tests__/index.test.jsx +0 -109
- package/src/__tests__/input-imperative.test.jsx +0 -144
- package/src/__tests__/keypad-label.test.jsx +0 -283
- package/src/__tests__/keypad-render.test.jsx +0 -123
- package/src/__tests__/latex-bridge.test.js +0 -389
- package/src/__tests__/mathlive-instance.test.js +0 -418
- package/src/__tests__/mount-race.test.jsx +0 -142
- package/src/__tests__/static-prompts.test.jsx +0 -364
- package/src/horizontal-keypad.jsx +0 -73
- package/src/index.jsx +0 -63
- package/src/keypad/index.jsx +0 -386
- package/src/keypad/keys-layout.js +0 -16
- package/src/keys/basic-operators.js +0 -32
- package/src/keys/chars.js +0 -5
- package/src/keys/comparison.js +0 -28
- package/src/keys/constants.js +0 -35
- package/src/keys/digits.js +0 -40
- package/src/keys/edit.js +0 -3
- package/src/keys/exponent.js +0 -28
- package/src/keys/fractions.js +0 -26
- package/src/keys/geometry.js +0 -149
- package/src/keys/grades.js +0 -367
- package/src/keys/index.js +0 -20
- package/src/keys/log.js +0 -22
- package/src/keys/logic.js +0 -15
- package/src/keys/matrices.js +0 -15
- package/src/keys/misc.js +0 -71
- package/src/keys/navigation.js +0 -8
- package/src/keys/operators.js +0 -10
- package/src/keys/statistics.js +0 -38
- package/src/keys/sub-sup.js +0 -15
- package/src/keys/trigonometry.js +0 -15
- package/src/keys/utils.js +0 -66
- package/src/keys/vars.js +0 -19
- package/src/latex-bridge.js +0 -524
- package/src/math-input.jsx +0 -115
- package/src/mathlive-instance.js +0 -582
- package/src/mf/common-styles.js +0 -210
- package/src/mf/index.js +0 -30
- package/src/mf/input.jsx +0 -319
- package/src/mf/static.jsx +0 -479
package/src/keypad/index.jsx
DELETED
|
@@ -1,386 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
|
-
import Button from '@mui/material/Button';
|
|
4
|
-
import IconButton from '@mui/material/IconButton';
|
|
5
|
-
import { styled } from '@mui/material/styles';
|
|
6
|
-
import debug from 'debug';
|
|
7
|
-
import { flatten } from 'lodash-es';
|
|
8
|
-
import { color } from '@pie-lib/render-ui';
|
|
9
|
-
|
|
10
|
-
import { baseSet } from '../keys';
|
|
11
|
-
import { sortKeys } from './keys-layout';
|
|
12
|
-
import { commonKeyboardStyles, rootIndexStyles } from '../mf/common-styles';
|
|
13
|
-
import { loadMathLive, latexToMarkup } from '../mathlive-instance';
|
|
14
|
-
|
|
15
|
-
const log = debug('pie-lib:math-input-mathlive:keypad');
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* A LaTeX keypad label.
|
|
19
|
-
*
|
|
20
|
-
* The MathQuill implementation rendered every LaTeX label as its own
|
|
21
|
-
* `MQ.StaticMath` instance. Here each label is static HTML produced once by
|
|
22
|
-
* `convertLatexToMarkup`, so a 40-key keypad no longer creates 40 live math
|
|
23
|
-
* instances.
|
|
24
|
-
*/
|
|
25
|
-
// Labels that the legacy keypad drew slanted. MathQuill styled `\parallel` as
|
|
26
|
-
// italic, which slants the two bars; MathLive draws it upright. A skew is used
|
|
27
|
-
// rather than `font-style: italic` so the slant does not depend on the font
|
|
28
|
-
// having an italic face for this glyph.
|
|
29
|
-
const SLANTED_LABELS = ['\\parallel'];
|
|
30
|
-
const SLANT = 'skewX(-15deg)';
|
|
31
|
-
// MathLive's `∥` has hairline bars next to the radical sign and the other keys, so
|
|
32
|
-
// they are thickened with a text stroke and stretched a little taller.
|
|
33
|
-
const SLANTED_STROKE = '0.03em currentColor';
|
|
34
|
-
const SLANTED_SCALE_Y = 1.25;
|
|
35
|
-
|
|
36
|
-
// The `color.*()` helpers must be called lazily, inside the styled callback.
|
|
37
|
-
// Evaluating them in a plain object literal runs them at module load, which
|
|
38
|
-
// breaks any consumer that mocks a subset of @pie-lib/render-ui.
|
|
39
|
-
const LabelHolder = styled('span', { shouldForwardProp: (prop) => prop !== 'slanted' })(({ slanted }) => ({
|
|
40
|
-
...(slanted && {
|
|
41
|
-
transform: `${SLANT} scaleY(${SLANTED_SCALE_Y})`,
|
|
42
|
-
'& *': { WebkitTextStroke: SLANTED_STROKE },
|
|
43
|
-
}),
|
|
44
|
-
pointerEvents: 'none',
|
|
45
|
-
textTransform: 'none',
|
|
46
|
-
color: color.text(),
|
|
47
|
-
// Deliberately inline-block, NOT inline-flex: MathLive's markup relies on
|
|
48
|
-
// normal inline flow. Making its spans flex items collapses their width, and
|
|
49
|
-
// stretchy accents render an <svg width="100%" preserveAspectRatio="none">
|
|
50
|
-
// that then squeezes into a spike instead of spanning the content.
|
|
51
|
-
display: 'inline-block',
|
|
52
|
-
textAlign: 'center',
|
|
53
|
-
lineHeight: 1,
|
|
54
|
-
// Keep a label from sizing its grid column. `overflow: hidden` also collapses
|
|
55
|
-
// the label's min-content contribution, so a wide accent cannot drag the
|
|
56
|
-
// column across the screen. The svg's own positioning is left to
|
|
57
|
-
// mathlive-static.css (injected by the package) - duplicating it here broke
|
|
58
|
-
// the accent's containing block.
|
|
59
|
-
maxWidth: '100%',
|
|
60
|
-
overflow: 'hidden',
|
|
61
|
-
// Answer-block / empty-slot boxes inside a label.
|
|
62
|
-
'& .ML__placeholder': {
|
|
63
|
-
backgroundColor: color.keypadEmptyPlaceholder ? color.keypadEmptyPlaceholder() : undefined,
|
|
64
|
-
},
|
|
65
|
-
// The stand-in glyph for an empty argument slot (see EMPTY_SLOT). Muted so it
|
|
66
|
-
// reads as "a slot goes here" rather than as part of the symbol, matching how
|
|
67
|
-
// MathQuill shaded `.mq-empty`.
|
|
68
|
-
'& [data-pie-empty]': {
|
|
69
|
-
opacity: 0.5,
|
|
70
|
-
},
|
|
71
|
-
// A readable index on the nth-root key. Carried by the label itself, not only
|
|
72
|
-
// by the keypad container, so it holds wherever a LatexLabel is mounted.
|
|
73
|
-
...rootIndexStyles,
|
|
74
|
-
}));
|
|
75
|
-
|
|
76
|
-
export class LatexLabel extends React.Component {
|
|
77
|
-
static propTypes = {
|
|
78
|
-
latex: PropTypes.string.isRequired,
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
constructor(props) {
|
|
82
|
-
super(props);
|
|
83
|
-
this.state = { markup: latexToMarkup(props.latex) };
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
async componentDidMount() {
|
|
87
|
-
// MathLive may not have finished loading when the keypad first mounts.
|
|
88
|
-
if (this.state.markup) {
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
await loadMathLive();
|
|
93
|
-
|
|
94
|
-
if (this.unmounted) {
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
const markup = latexToMarkup(this.props.latex);
|
|
99
|
-
|
|
100
|
-
if (markup) {
|
|
101
|
-
this.setState({ markup });
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// Still nothing: the engine is genuinely unavailable (a missing chunk, a
|
|
106
|
-
// blocked request). Keep the raw-latex fallback visible rather than an
|
|
107
|
-
// empty button, and log once so this is diagnosable.
|
|
108
|
-
if (!LatexLabel.warned) {
|
|
109
|
-
LatexLabel.warned = true;
|
|
110
|
-
log('MathLive unavailable - keypad labels are falling back to raw latex');
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
componentDidUpdate(prevProps) {
|
|
115
|
-
if (prevProps.latex !== this.props.latex) {
|
|
116
|
-
this.setState({ markup: latexToMarkup(this.props.latex) });
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
componentWillUnmount() {
|
|
121
|
-
this.unmounted = true;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
render() {
|
|
125
|
-
const { markup } = this.state;
|
|
126
|
-
|
|
127
|
-
// Fall back to the raw latex so a button is never blank.
|
|
128
|
-
return markup ? (
|
|
129
|
-
// eslint-disable-next-line react/no-danger
|
|
130
|
-
<LabelHolder slanted={SLANTED_LABELS.includes(this.props.latex)} dangerouslySetInnerHTML={{ __html: markup }} />
|
|
131
|
-
) : (
|
|
132
|
-
<LabelHolder slanted={SLANTED_LABELS.includes(this.props.latex)}>{this.props.latex}</LabelHolder>
|
|
133
|
-
);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
const createCustomLayout = (layoutObj) => {
|
|
138
|
-
if (layoutObj) {
|
|
139
|
-
return {
|
|
140
|
-
gridTemplateColumns: `repeat(${layoutObj.columns}, minmax(min-content, 150px))`,
|
|
141
|
-
gridTemplateRows: `repeat(${layoutObj.rows}, minmax(40px, 60px))`,
|
|
142
|
-
gridAutoFlow: 'initial',
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
return {};
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
const KeyPadContainer = styled('div')(() => ({
|
|
150
|
-
...commonKeyboardStyles,
|
|
151
|
-
width: '100%',
|
|
152
|
-
display: 'grid',
|
|
153
|
-
gridTemplateRows: 'repeat(5, minmax(40px, 60px))',
|
|
154
|
-
gridRowGap: '0px',
|
|
155
|
-
gridColumnGap: '0px',
|
|
156
|
-
gridAutoFlow: 'column',
|
|
157
|
-
'&.character': {
|
|
158
|
-
textTransform: 'initial !important',
|
|
159
|
-
gridTemplateRows: 'repeat(5, minmax(40px, 50px)) !important',
|
|
160
|
-
},
|
|
161
|
-
'&.language': {
|
|
162
|
-
gridTemplateRows: 'repeat(4, minmax(40px, 50px)) !important',
|
|
163
|
-
'& *': {
|
|
164
|
-
fontFamily: 'Roboto, Helvetica, Arial, sans-serif !important',
|
|
165
|
-
},
|
|
166
|
-
},
|
|
167
|
-
}));
|
|
168
|
-
|
|
169
|
-
const buttonBackground = (category) => ({
|
|
170
|
-
backgroundColor: category === 'operators' ? color.keypadButtonOperator() : color.keypadButton(),
|
|
171
|
-
'&:hover': {
|
|
172
|
-
backgroundColor: category === 'operators' ? color.keypadButtonOperatorHover() : color.keypadButtonHover(),
|
|
173
|
-
},
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
const StyledButton = styled(Button)(({ category, isDelete, isComma, isDot }) => ({
|
|
177
|
-
minWidth: 'auto',
|
|
178
|
-
textTransform: 'none',
|
|
179
|
-
fontSize: isComma || isDot ? '200% !important' : '140% !important',
|
|
180
|
-
lineHeight: isComma || isDot ? '100%' : 'normal',
|
|
181
|
-
color: color.text(),
|
|
182
|
-
...buttonBackground(category),
|
|
183
|
-
borderRadius: 0,
|
|
184
|
-
...(isDelete && {
|
|
185
|
-
fontFamily: 'Roboto, Helvetica, Arial, sans-serif !important',
|
|
186
|
-
}),
|
|
187
|
-
}));
|
|
188
|
-
|
|
189
|
-
const StyledLatexButtonWrapper = styled(Button)(({ category }) => ({
|
|
190
|
-
textTransform: 'none',
|
|
191
|
-
padding: 0,
|
|
192
|
-
margin: 0,
|
|
193
|
-
fontSize: '110% !important',
|
|
194
|
-
minWidth: 'auto',
|
|
195
|
-
borderRadius: 0,
|
|
196
|
-
...buttonBackground(category),
|
|
197
|
-
}));
|
|
198
|
-
|
|
199
|
-
const StyledIconButton = styled(IconButton)(({ category }) => ({
|
|
200
|
-
minWidth: 'auto',
|
|
201
|
-
...buttonBackground(category),
|
|
202
|
-
borderRadius: 0,
|
|
203
|
-
'& .icon': {
|
|
204
|
-
height: '30px',
|
|
205
|
-
},
|
|
206
|
-
}));
|
|
207
|
-
|
|
208
|
-
export class KeyPad extends React.Component {
|
|
209
|
-
static propTypes = {
|
|
210
|
-
className: PropTypes.string,
|
|
211
|
-
controlledKeypadMode: PropTypes.bool,
|
|
212
|
-
baseSet: PropTypes.array,
|
|
213
|
-
additionalKeys: PropTypes.array,
|
|
214
|
-
layoutForKeyPad: PropTypes.object,
|
|
215
|
-
onPress: PropTypes.func.isRequired,
|
|
216
|
-
onFocus: PropTypes.func,
|
|
217
|
-
noDecimal: PropTypes.bool,
|
|
218
|
-
setKeypadInteraction: PropTypes.func,
|
|
219
|
-
mode: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
220
|
-
};
|
|
221
|
-
|
|
222
|
-
static defaultProps = {
|
|
223
|
-
baseSet: baseSet,
|
|
224
|
-
noDecimal: false,
|
|
225
|
-
};
|
|
226
|
-
|
|
227
|
-
constructor(props) {
|
|
228
|
-
super(props);
|
|
229
|
-
this.keypadRef = React.createRef();
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
componentDidMount() {
|
|
233
|
-
// Ensure MathLive is available for the LaTeX labels.
|
|
234
|
-
loadMathLive();
|
|
235
|
-
|
|
236
|
-
const keyPadElement = this.keypadRef?.current;
|
|
237
|
-
const mainContainer = keyPadElement?.closest('.main-container');
|
|
238
|
-
const currentToolbar = keyPadElement?.closest('.pie-toolbar');
|
|
239
|
-
|
|
240
|
-
// need only for math keyboard so we need also controlledKeypadMode
|
|
241
|
-
if (this.props.controlledKeypadMode && mainContainer && currentToolbar) {
|
|
242
|
-
const mainContainerPosition = mainContainer.getBoundingClientRect();
|
|
243
|
-
const currentToolbarPosition = currentToolbar.getBoundingClientRect();
|
|
244
|
-
const difference =
|
|
245
|
-
mainContainerPosition.top +
|
|
246
|
-
mainContainerPosition.height -
|
|
247
|
-
(currentToolbarPosition.top + currentToolbarPosition.height);
|
|
248
|
-
|
|
249
|
-
if (difference < 0) {
|
|
250
|
-
const totalHeight = mainContainerPosition.height + mainContainerPosition.top - difference;
|
|
251
|
-
|
|
252
|
-
mainContainer.style.height = `${totalHeight}px`;
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
if (keyPadElement) {
|
|
257
|
-
keyPadElement.addEventListener('touchstart', this.handleKeypadInteraction, true);
|
|
258
|
-
keyPadElement.addEventListener('mousedown', this.handleKeypadInteraction, true);
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
componentWillUnmount() {
|
|
263
|
-
const keyPadElement = this.keypadRef?.current;
|
|
264
|
-
|
|
265
|
-
if (this.props.controlledKeypadMode && keyPadElement) {
|
|
266
|
-
const mainContainer = keyPadElement.closest('.main-container');
|
|
267
|
-
|
|
268
|
-
if (mainContainer) {
|
|
269
|
-
mainContainer.style.height = 'unset';
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
if (keyPadElement) {
|
|
274
|
-
keyPadElement.removeEventListener('touchstart', this.handleKeypadInteraction, true);
|
|
275
|
-
keyPadElement.removeEventListener('mousedown', this.handleKeypadInteraction, true);
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
handleKeypadInteraction = () => {
|
|
280
|
-
if (this.props.setKeypadInteraction) {
|
|
281
|
-
this.props.setKeypadInteraction(true);
|
|
282
|
-
}
|
|
283
|
-
};
|
|
284
|
-
|
|
285
|
-
buttonClick = (key) => {
|
|
286
|
-
log('[buttonClick]', key);
|
|
287
|
-
this.props.onPress(key);
|
|
288
|
-
};
|
|
289
|
-
|
|
290
|
-
flowKeys = (base, extras) => flatten([...sortKeys(base), ...sortKeys(extras)]);
|
|
291
|
-
|
|
292
|
-
keyIsNotAllowed = (key) => {
|
|
293
|
-
const { noDecimal } = this.props;
|
|
294
|
-
|
|
295
|
-
return !!(((key.write === '.' && key.label === '.') || (key.write === ',' && key.label === ',')) && noDecimal);
|
|
296
|
-
};
|
|
297
|
-
|
|
298
|
-
render() {
|
|
299
|
-
const { className, baseSet: base, additionalKeys, layoutForKeyPad, onFocus, mode } = this.props;
|
|
300
|
-
|
|
301
|
-
const noBaseSet = ['non-negative-integers', 'integers', 'decimals', 'fractions', 'item-authoring', 'language'];
|
|
302
|
-
const keysWithoutBaseSet = noBaseSet.includes(mode);
|
|
303
|
-
const allKeys = keysWithoutBaseSet
|
|
304
|
-
? this.flowKeys([], additionalKeys || [])
|
|
305
|
-
: this.flowKeys(base, additionalKeys || []);
|
|
306
|
-
|
|
307
|
-
const shift = allKeys.length % 5 ? 1 : 0;
|
|
308
|
-
const style = {
|
|
309
|
-
gridTemplateColumns: `repeat(${Math.floor(allKeys.length / 5) + shift}, minmax(min-content, 150px))`,
|
|
310
|
-
...createCustomLayout(layoutForKeyPad),
|
|
311
|
-
};
|
|
312
|
-
|
|
313
|
-
return (
|
|
314
|
-
<KeyPadContainer
|
|
315
|
-
ref={this.keypadRef}
|
|
316
|
-
className={[className, mode].filter(Boolean).join(' ')}
|
|
317
|
-
style={style}
|
|
318
|
-
onFocus={onFocus}
|
|
319
|
-
>
|
|
320
|
-
{allKeys.map((k, index) => {
|
|
321
|
-
if (!k) {
|
|
322
|
-
return <span key={`empty-${index}`} />;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
const key = `${k.label || k.latex || k.command}-${index}`;
|
|
326
|
-
const category = !keysWithoutBaseSet ? k.category : undefined;
|
|
327
|
-
const extra = { ...(k.actions || {}), ...(k.extraProps || {}) };
|
|
328
|
-
const onClick = this.buttonClick.bind(this, k);
|
|
329
|
-
const disabled = this.keyIsNotAllowed(k);
|
|
330
|
-
const ariaLabel = k.ariaLabel ? k.ariaLabel : k.name || k.label;
|
|
331
|
-
|
|
332
|
-
if (k.latex) {
|
|
333
|
-
return (
|
|
334
|
-
<StyledLatexButtonWrapper
|
|
335
|
-
key={key}
|
|
336
|
-
onClick={onClick}
|
|
337
|
-
disabled={disabled}
|
|
338
|
-
category={category}
|
|
339
|
-
aria-label={ariaLabel}
|
|
340
|
-
{...extra}
|
|
341
|
-
>
|
|
342
|
-
<LatexLabel latex={k.latex} />
|
|
343
|
-
</StyledLatexButtonWrapper>
|
|
344
|
-
);
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
if (k.label) {
|
|
348
|
-
return (
|
|
349
|
-
<StyledButton
|
|
350
|
-
key={key}
|
|
351
|
-
onClick={onClick}
|
|
352
|
-
disabled={disabled}
|
|
353
|
-
category={category}
|
|
354
|
-
isDelete={k.label === '⌫'}
|
|
355
|
-
isComma={k.label === ','}
|
|
356
|
-
isDot={k.label === '.'}
|
|
357
|
-
aria-label={ariaLabel}
|
|
358
|
-
{...extra}
|
|
359
|
-
>
|
|
360
|
-
{k.label}
|
|
361
|
-
</StyledButton>
|
|
362
|
-
);
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
const Icon = k.icon ? k.icon : 'div';
|
|
366
|
-
|
|
367
|
-
return (
|
|
368
|
-
<StyledIconButton
|
|
369
|
-
key={key}
|
|
370
|
-
tabIndex={'-1'}
|
|
371
|
-
onClick={onClick}
|
|
372
|
-
disabled={disabled}
|
|
373
|
-
category={category}
|
|
374
|
-
size="large"
|
|
375
|
-
{...extra}
|
|
376
|
-
>
|
|
377
|
-
<Icon className="icon" />
|
|
378
|
-
</StyledIconButton>
|
|
379
|
-
);
|
|
380
|
-
})}
|
|
381
|
-
</KeyPadContainer>
|
|
382
|
-
);
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
export default KeyPad;
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { times, zip } from 'lodash-es';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Sort additional keys.
|
|
5
|
-
*
|
|
6
|
-
* Expects an array of rows.
|
|
7
|
-
* @param {} keys
|
|
8
|
-
*/
|
|
9
|
-
export const sortKeys = (keys) => {
|
|
10
|
-
// add any missing rows
|
|
11
|
-
times(5 - keys.length, () => keys.push([]));
|
|
12
|
-
|
|
13
|
-
const out = zip.apply(null, keys);
|
|
14
|
-
|
|
15
|
-
return out;
|
|
16
|
-
};
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { DIVIDE, MULTIPLY } from './chars';
|
|
2
|
-
import { mkSet } from './utils';
|
|
3
|
-
|
|
4
|
-
const set = mkSet('operators');
|
|
5
|
-
|
|
6
|
-
export const equals = set({
|
|
7
|
-
write: '=',
|
|
8
|
-
label: '=',
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
export const plus = set({
|
|
12
|
-
write: '+',
|
|
13
|
-
label: '+',
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
export const minus = set({
|
|
17
|
-
write: '−',
|
|
18
|
-
label: '−',
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
export const divide = set({
|
|
22
|
-
name: 'divide',
|
|
23
|
-
label: DIVIDE,
|
|
24
|
-
command: '\\divide',
|
|
25
|
-
otherNotation: '\\div',
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
export const multiply = set({
|
|
29
|
-
name: 'multiply',
|
|
30
|
-
label: MULTIPLY,
|
|
31
|
-
command: '\\times',
|
|
32
|
-
});
|
package/src/keys/chars.js
DELETED
package/src/keys/comparison.js
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
const set = (o) => ({ ...o, category: 'comparison' });
|
|
2
|
-
|
|
3
|
-
export const lessThan = set({
|
|
4
|
-
name: 'Less than',
|
|
5
|
-
latex: '<',
|
|
6
|
-
command: '\\lt',
|
|
7
|
-
});
|
|
8
|
-
|
|
9
|
-
export const greaterThan = set({
|
|
10
|
-
name: 'Greater than',
|
|
11
|
-
latex: '>',
|
|
12
|
-
command: '\\gt',
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
export const lessThanEqual = set({
|
|
16
|
-
name: 'Less than or equal',
|
|
17
|
-
latex: '\\le',
|
|
18
|
-
symbol: '<=',
|
|
19
|
-
command: '\\le',
|
|
20
|
-
ariaLabel: 'less than or equal to',
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
export const greaterThanEqual = set({
|
|
24
|
-
name: 'Greater than or equal',
|
|
25
|
-
symbol: '>=',
|
|
26
|
-
command: '\\ge',
|
|
27
|
-
latex: '\\ge',
|
|
28
|
-
});
|
package/src/keys/constants.js
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { mkSet } from './utils';
|
|
2
|
-
|
|
3
|
-
const set = mkSet('constants');
|
|
4
|
-
|
|
5
|
-
export const pi = set({
|
|
6
|
-
name: 'Pi',
|
|
7
|
-
label: 'π',
|
|
8
|
-
latex: '\\pi',
|
|
9
|
-
command: '\\pi',
|
|
10
|
-
category: 'constants',
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
export const eulers = set({
|
|
14
|
-
name: 'Eulers',
|
|
15
|
-
label: 'e',
|
|
16
|
-
latex: 'e',
|
|
17
|
-
command: 'e',
|
|
18
|
-
category: 'constants',
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
export const infinity = set({
|
|
22
|
-
name: 'Infinity',
|
|
23
|
-
label: '\\infty',
|
|
24
|
-
latex: '\\infty',
|
|
25
|
-
command: '\\infty',
|
|
26
|
-
category: 'constants',
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
export const halfInfinity = set({
|
|
30
|
-
name: 'Half Infinity',
|
|
31
|
-
label: '\\propto',
|
|
32
|
-
latex: '\\propto',
|
|
33
|
-
command: '\\propto',
|
|
34
|
-
category: 'constants',
|
|
35
|
-
});
|
package/src/keys/digits.js
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { times } from 'lodash-es';
|
|
2
|
-
|
|
3
|
-
const digitMap = {
|
|
4
|
-
0: 'zero',
|
|
5
|
-
1: 'one',
|
|
6
|
-
2: 'two',
|
|
7
|
-
3: 'three',
|
|
8
|
-
4: 'four',
|
|
9
|
-
5: 'five',
|
|
10
|
-
6: 'six',
|
|
11
|
-
7: 'seven',
|
|
12
|
-
8: 'eight',
|
|
13
|
-
9: 'nine',
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
const comma = { name: 'comma', label: ',', write: ',', category: 'digit' };
|
|
17
|
-
|
|
18
|
-
const decimalPoint = {
|
|
19
|
-
name: 'decimal-point',
|
|
20
|
-
label: '.',
|
|
21
|
-
write: '.',
|
|
22
|
-
category: 'digit',
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
export default times(10, String)
|
|
26
|
-
.map((n) => {
|
|
27
|
-
return {
|
|
28
|
-
name: digitMap[n],
|
|
29
|
-
write: n,
|
|
30
|
-
label: n,
|
|
31
|
-
category: 'digit',
|
|
32
|
-
};
|
|
33
|
-
})
|
|
34
|
-
.reduce(
|
|
35
|
-
(acc, o) => {
|
|
36
|
-
acc[o.name] = o;
|
|
37
|
-
return acc;
|
|
38
|
-
},
|
|
39
|
-
{ comma, decimalPoint },
|
|
40
|
-
);
|
package/src/keys/edit.js
DELETED
package/src/keys/exponent.js
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { mkSet } from './utils';
|
|
2
|
-
|
|
3
|
-
const set = mkSet('exponent');
|
|
4
|
-
|
|
5
|
-
export const squared = set({
|
|
6
|
-
name: 'Squared',
|
|
7
|
-
latex: 'x^2',
|
|
8
|
-
write: '^2',
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
export const xToPowerOfN = set({
|
|
12
|
-
name: 'X to the power of n',
|
|
13
|
-
latex: 'x^{}',
|
|
14
|
-
command: '^',
|
|
15
|
-
ariaLabel: 'exponent',
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
export const squareRoot = set({
|
|
19
|
-
name: 'Square root',
|
|
20
|
-
latex: '\\sqrt{}',
|
|
21
|
-
command: '\\sqrt',
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
export const nthRoot = set({
|
|
25
|
-
name: 'Nth root',
|
|
26
|
-
latex: '\\sqrt[{}]{}',
|
|
27
|
-
command: '\\nthroot',
|
|
28
|
-
});
|
package/src/keys/fractions.js
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { mkSet } from './utils';
|
|
2
|
-
|
|
3
|
-
const set = mkSet('fractions');
|
|
4
|
-
|
|
5
|
-
export const blankOverBlank = set({
|
|
6
|
-
name: 'blank/blank',
|
|
7
|
-
latex: '\\frac{}{}',
|
|
8
|
-
command: '\\frac',
|
|
9
|
-
ariaLabel: 'fraction',
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
export const xOverBlank = set({
|
|
13
|
-
latex: '\\frac{x}{ }',
|
|
14
|
-
name: 'X/blank',
|
|
15
|
-
label: 'x/[]',
|
|
16
|
-
command: '/',
|
|
17
|
-
ariaLabel: 'x over blank fraction',
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
export const xBlankBlank = set({
|
|
21
|
-
name: 'X (blank/blank)',
|
|
22
|
-
latex: 'x\\frac{}{}',
|
|
23
|
-
label: 'x([]/[])',
|
|
24
|
-
command: '\\frac',
|
|
25
|
-
ariaLabel: 'mixed number',
|
|
26
|
-
});
|