@pie-lib/math-input-mathlive 1.0.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.
Files changed (110) hide show
  1. package/README.md +119 -0
  2. package/lib/__tests__/index.test.js +118 -0
  3. package/lib/__tests__/index.test.js.map +1 -0
  4. package/lib/__tests__/latex-bridge.test.js +186 -0
  5. package/lib/__tests__/latex-bridge.test.js.map +1 -0
  6. package/lib/__tests__/mathlive-instance.test.js +137 -0
  7. package/lib/__tests__/mathlive-instance.test.js.map +1 -0
  8. package/lib/horizontal-keypad.js +101 -0
  9. package/lib/horizontal-keypad.js.map +1 -0
  10. package/lib/index.js +143 -0
  11. package/lib/index.js.map +1 -0
  12. package/lib/keypad/index.js +365 -0
  13. package/lib/keypad/index.js.map +1 -0
  14. package/lib/keypad/keys-layout.js +22 -0
  15. package/lib/keypad/keys-layout.js.map +1 -0
  16. package/lib/keys/basic-operators.js +33 -0
  17. package/lib/keys/basic-operators.js.map +1 -0
  18. package/lib/keys/chars.js +12 -0
  19. package/lib/keys/chars.js.map +1 -0
  20. package/lib/keys/comparison.js +39 -0
  21. package/lib/keys/comparison.js.map +1 -0
  22. package/lib/keys/constants.js +37 -0
  23. package/lib/keys/constants.js.map +1 -0
  24. package/lib/keys/digits.js +46 -0
  25. package/lib/keys/digits.js.map +1 -0
  26. package/lib/keys/edit.js +14 -0
  27. package/lib/keys/edit.js.map +1 -0
  28. package/lib/keys/exponent.js +30 -0
  29. package/lib/keys/exponent.js.map +1 -0
  30. package/lib/keys/fractions.js +29 -0
  31. package/lib/keys/fractions.js.map +1 -0
  32. package/lib/keys/geometry.js +140 -0
  33. package/lib/keys/geometry.js.map +1 -0
  34. package/lib/keys/grades.js +259 -0
  35. package/lib/keys/grades.js.map +1 -0
  36. package/lib/keys/index.js +35 -0
  37. package/lib/keys/index.js.map +1 -0
  38. package/lib/keys/log.js +27 -0
  39. package/lib/keys/log.js.map +1 -0
  40. package/lib/keys/logic.js +19 -0
  41. package/lib/keys/logic.js.map +1 -0
  42. package/lib/keys/matrices.js +19 -0
  43. package/lib/keys/matrices.js.map +1 -0
  44. package/lib/keys/misc.js +62 -0
  45. package/lib/keys/misc.js.map +1 -0
  46. package/lib/keys/navigation.js +20 -0
  47. package/lib/keys/navigation.js.map +1 -0
  48. package/lib/keys/operators.js +15 -0
  49. package/lib/keys/operators.js.map +1 -0
  50. package/lib/keys/statistics.js +40 -0
  51. package/lib/keys/statistics.js.map +1 -0
  52. package/lib/keys/sub-sup.js +19 -0
  53. package/lib/keys/sub-sup.js.map +1 -0
  54. package/lib/keys/trigonometry.js +45 -0
  55. package/lib/keys/trigonometry.js.map +1 -0
  56. package/lib/keys/utils.js +87 -0
  57. package/lib/keys/utils.js.map +1 -0
  58. package/lib/keys/vars.js +24 -0
  59. package/lib/keys/vars.js.map +1 -0
  60. package/lib/latex-bridge.js +195 -0
  61. package/lib/latex-bridge.js.map +1 -0
  62. package/lib/math-input.js +143 -0
  63. package/lib/math-input.js.map +1 -0
  64. package/lib/mathlive-instance.js +319 -0
  65. package/lib/mathlive-instance.js.map +1 -0
  66. package/lib/mf/common-styles.js +111 -0
  67. package/lib/mf/common-styles.js.map +1 -0
  68. package/lib/mf/index.js +72 -0
  69. package/lib/mf/index.js.map +1 -0
  70. package/lib/mf/input.js +266 -0
  71. package/lib/mf/input.js.map +1 -0
  72. package/lib/mf/static.js +396 -0
  73. package/lib/mf/static.js.map +1 -0
  74. package/package.json +31 -0
  75. package/src/__tests__/index.test.jsx +109 -0
  76. package/src/__tests__/latex-bridge.test.js +151 -0
  77. package/src/__tests__/mathlive-instance.test.js +130 -0
  78. package/src/horizontal-keypad.jsx +73 -0
  79. package/src/index.jsx +63 -0
  80. package/src/keypad/index.jsx +335 -0
  81. package/src/keypad/keys-layout.js +16 -0
  82. package/src/keys/basic-operators.js +32 -0
  83. package/src/keys/chars.js +5 -0
  84. package/src/keys/comparison.js +28 -0
  85. package/src/keys/constants.js +35 -0
  86. package/src/keys/digits.js +40 -0
  87. package/src/keys/edit.js +3 -0
  88. package/src/keys/exponent.js +28 -0
  89. package/src/keys/fractions.js +26 -0
  90. package/src/keys/geometry.js +144 -0
  91. package/src/keys/grades.js +367 -0
  92. package/src/keys/index.js +20 -0
  93. package/src/keys/log.js +22 -0
  94. package/src/keys/logic.js +15 -0
  95. package/src/keys/matrices.js +15 -0
  96. package/src/keys/misc.js +65 -0
  97. package/src/keys/navigation.js +8 -0
  98. package/src/keys/operators.js +10 -0
  99. package/src/keys/statistics.js +38 -0
  100. package/src/keys/sub-sup.js +15 -0
  101. package/src/keys/trigonometry.js +15 -0
  102. package/src/keys/utils.js +66 -0
  103. package/src/keys/vars.js +19 -0
  104. package/src/latex-bridge.js +190 -0
  105. package/src/math-input.jsx +115 -0
  106. package/src/mathlive-instance.js +286 -0
  107. package/src/mf/common-styles.js +108 -0
  108. package/src/mf/index.js +26 -0
  109. package/src/mf/input.jsx +223 -0
  110. package/src/mf/static.jsx +358 -0
@@ -0,0 +1,335 @@
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 } 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
+ const LabelHolder = styled('span')({
26
+ pointerEvents: 'none',
27
+ textTransform: 'none',
28
+ color: color.text(),
29
+ display: 'inline-flex',
30
+ alignItems: 'center',
31
+ justifyContent: 'center',
32
+ lineHeight: 1,
33
+ // Answer-block / empty-slot boxes inside a label.
34
+ '& .ML__placeholder': {
35
+ backgroundColor: color.keypadEmptyPlaceholder(),
36
+ },
37
+ });
38
+
39
+ export class LatexLabel extends React.Component {
40
+ static propTypes = {
41
+ latex: PropTypes.string.isRequired,
42
+ };
43
+
44
+ constructor(props) {
45
+ super(props);
46
+ this.state = { markup: latexToMarkup(props.latex) };
47
+ }
48
+
49
+ async componentDidMount() {
50
+ // MathLive may not have finished loading when the keypad first mounts.
51
+ if (!this.state.markup) {
52
+ await loadMathLive();
53
+
54
+ if (!this.unmounted) {
55
+ this.setState({ markup: latexToMarkup(this.props.latex) });
56
+ }
57
+ }
58
+ }
59
+
60
+ componentDidUpdate(prevProps) {
61
+ if (prevProps.latex !== this.props.latex) {
62
+ this.setState({ markup: latexToMarkup(this.props.latex) });
63
+ }
64
+ }
65
+
66
+ componentWillUnmount() {
67
+ this.unmounted = true;
68
+ }
69
+
70
+ render() {
71
+ const { markup } = this.state;
72
+
73
+ // Fall back to the raw latex so a button is never blank.
74
+ return markup ? (
75
+ // eslint-disable-next-line react/no-danger
76
+ <LabelHolder dangerouslySetInnerHTML={{ __html: markup }} />
77
+ ) : (
78
+ <LabelHolder>{this.props.latex}</LabelHolder>
79
+ );
80
+ }
81
+ }
82
+
83
+ const createCustomLayout = (layoutObj) => {
84
+ if (layoutObj) {
85
+ return {
86
+ gridTemplateColumns: `repeat(${layoutObj.columns}, minmax(min-content, 150px))`,
87
+ gridTemplateRows: `repeat(${layoutObj.rows}, minmax(40px, 60px))`,
88
+ gridAutoFlow: 'initial',
89
+ };
90
+ }
91
+
92
+ return {};
93
+ };
94
+
95
+ const KeyPadContainer = styled('div')(() => ({
96
+ ...commonKeyboardStyles,
97
+ width: '100%',
98
+ display: 'grid',
99
+ gridTemplateRows: 'repeat(5, minmax(40px, 60px))',
100
+ gridRowGap: '0px',
101
+ gridColumnGap: '0px',
102
+ gridAutoFlow: 'column',
103
+ '&.character': {
104
+ textTransform: 'initial !important',
105
+ gridTemplateRows: 'repeat(5, minmax(40px, 50px)) !important',
106
+ },
107
+ '&.language': {
108
+ gridTemplateRows: 'repeat(4, minmax(40px, 50px)) !important',
109
+ '& *': {
110
+ fontFamily: 'Roboto, Helvetica, Arial, sans-serif !important',
111
+ },
112
+ },
113
+ }));
114
+
115
+ const buttonBackground = (category) => ({
116
+ backgroundColor: category === 'operators' ? color.keypadButtonOperator() : color.keypadButton(),
117
+ '&:hover': {
118
+ backgroundColor: category === 'operators' ? color.keypadButtonOperatorHover() : color.keypadButtonHover(),
119
+ },
120
+ });
121
+
122
+ const StyledButton = styled(Button)(({ category, isDelete, isComma, isDot }) => ({
123
+ minWidth: 'auto',
124
+ textTransform: 'none',
125
+ fontSize: isComma || isDot ? '200% !important' : '140% !important',
126
+ lineHeight: isComma || isDot ? '100%' : 'normal',
127
+ color: color.text(),
128
+ ...buttonBackground(category),
129
+ borderRadius: 0,
130
+ ...(isDelete && {
131
+ fontFamily: 'Roboto, Helvetica, Arial, sans-serif !important',
132
+ }),
133
+ }));
134
+
135
+ const StyledLatexButtonWrapper = styled(Button)(({ category }) => ({
136
+ textTransform: 'none',
137
+ padding: 0,
138
+ margin: 0,
139
+ fontSize: '110% !important',
140
+ minWidth: 'auto',
141
+ borderRadius: 0,
142
+ ...buttonBackground(category),
143
+ }));
144
+
145
+ const StyledIconButton = styled(IconButton)(({ category }) => ({
146
+ minWidth: 'auto',
147
+ ...buttonBackground(category),
148
+ borderRadius: 0,
149
+ '& .icon': {
150
+ height: '30px',
151
+ },
152
+ }));
153
+
154
+ export class KeyPad extends React.Component {
155
+ static propTypes = {
156
+ className: PropTypes.string,
157
+ controlledKeypadMode: PropTypes.bool,
158
+ baseSet: PropTypes.array,
159
+ additionalKeys: PropTypes.array,
160
+ layoutForKeyPad: PropTypes.object,
161
+ onPress: PropTypes.func.isRequired,
162
+ onFocus: PropTypes.func,
163
+ noDecimal: PropTypes.bool,
164
+ setKeypadInteraction: PropTypes.func,
165
+ mode: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
166
+ };
167
+
168
+ static defaultProps = {
169
+ baseSet: baseSet,
170
+ noDecimal: false,
171
+ };
172
+
173
+ constructor(props) {
174
+ super(props);
175
+ this.keypadRef = React.createRef();
176
+ }
177
+
178
+ componentDidMount() {
179
+ // Ensure MathLive is available for the LaTeX labels.
180
+ loadMathLive();
181
+
182
+ const keyPadElement = this.keypadRef?.current;
183
+ const mainContainer = keyPadElement?.closest('.main-container');
184
+ const currentToolbar = keyPadElement?.closest('.pie-toolbar');
185
+
186
+ // need only for math keyboard so we need also controlledKeypadMode
187
+ if (this.props.controlledKeypadMode && mainContainer && currentToolbar) {
188
+ const mainContainerPosition = mainContainer.getBoundingClientRect();
189
+ const currentToolbarPosition = currentToolbar.getBoundingClientRect();
190
+ const difference =
191
+ mainContainerPosition.top +
192
+ mainContainerPosition.height -
193
+ (currentToolbarPosition.top + currentToolbarPosition.height);
194
+
195
+ if (difference < 0) {
196
+ const totalHeight = mainContainerPosition.height + mainContainerPosition.top - difference;
197
+
198
+ mainContainer.style.height = `${totalHeight}px`;
199
+ }
200
+ }
201
+
202
+ if (keyPadElement) {
203
+ keyPadElement.addEventListener('touchstart', this.handleKeypadInteraction, true);
204
+ keyPadElement.addEventListener('mousedown', this.handleKeypadInteraction, true);
205
+ }
206
+ }
207
+
208
+ componentWillUnmount() {
209
+ const keyPadElement = this.keypadRef?.current;
210
+
211
+ if (this.props.controlledKeypadMode && keyPadElement) {
212
+ const mainContainer = keyPadElement.closest('.main-container');
213
+
214
+ if (mainContainer) {
215
+ mainContainer.style.height = 'unset';
216
+ }
217
+ }
218
+
219
+ if (keyPadElement) {
220
+ keyPadElement.removeEventListener('touchstart', this.handleKeypadInteraction, true);
221
+ keyPadElement.removeEventListener('mousedown', this.handleKeypadInteraction, true);
222
+ }
223
+ }
224
+
225
+ handleKeypadInteraction = () => {
226
+ if (this.props.setKeypadInteraction) {
227
+ this.props.setKeypadInteraction(true);
228
+ }
229
+ };
230
+
231
+ buttonClick = (key) => {
232
+ log('[buttonClick]', key);
233
+ this.props.onPress(key);
234
+ };
235
+
236
+ flowKeys = (base, extras) => flatten([...sortKeys(base), ...sortKeys(extras)]);
237
+
238
+ keyIsNotAllowed = (key) => {
239
+ const { noDecimal } = this.props;
240
+
241
+ return !!(
242
+ ((key.write === '.' && key.label === '.') || (key.write === ',' && key.label === ',')) &&
243
+ noDecimal
244
+ );
245
+ };
246
+
247
+ render() {
248
+ const { className, baseSet: base, additionalKeys, layoutForKeyPad, onFocus, mode } = this.props;
249
+
250
+ const noBaseSet = ['non-negative-integers', 'integers', 'decimals', 'fractions', 'item-authoring', 'language'];
251
+ const keysWithoutBaseSet = noBaseSet.includes(mode);
252
+ const allKeys = keysWithoutBaseSet
253
+ ? this.flowKeys([], additionalKeys || [])
254
+ : this.flowKeys(base, additionalKeys || []);
255
+
256
+ const shift = allKeys.length % 5 ? 1 : 0;
257
+ const style = {
258
+ gridTemplateColumns: `repeat(${Math.floor(allKeys.length / 5) + shift}, minmax(min-content, 150px))`,
259
+ ...createCustomLayout(layoutForKeyPad),
260
+ };
261
+
262
+ return (
263
+ <KeyPadContainer
264
+ ref={this.keypadRef}
265
+ className={[className, mode].filter(Boolean).join(' ')}
266
+ style={style}
267
+ onFocus={onFocus}
268
+ >
269
+ {allKeys.map((k, index) => {
270
+ if (!k) {
271
+ return <span key={`empty-${index}`} />;
272
+ }
273
+
274
+ const key = `${k.label || k.latex || k.command}-${index}`;
275
+ const category = !keysWithoutBaseSet ? k.category : undefined;
276
+ const extra = { ...(k.actions || {}), ...(k.extraProps || {}) };
277
+ const onClick = this.buttonClick.bind(this, k);
278
+ const disabled = this.keyIsNotAllowed(k);
279
+ const ariaLabel = k.ariaLabel ? k.ariaLabel : k.name || k.label;
280
+
281
+ if (k.latex) {
282
+ return (
283
+ <StyledLatexButtonWrapper
284
+ key={key}
285
+ onClick={onClick}
286
+ disabled={disabled}
287
+ category={category}
288
+ aria-label={ariaLabel}
289
+ {...extra}
290
+ >
291
+ <LatexLabel latex={k.latex} />
292
+ </StyledLatexButtonWrapper>
293
+ );
294
+ }
295
+
296
+ if (k.label) {
297
+ return (
298
+ <StyledButton
299
+ key={key}
300
+ onClick={onClick}
301
+ disabled={disabled}
302
+ category={category}
303
+ isDelete={k.label === '⌫'}
304
+ isComma={k.label === ','}
305
+ isDot={k.label === '.'}
306
+ aria-label={ariaLabel}
307
+ {...extra}
308
+ >
309
+ {k.label}
310
+ </StyledButton>
311
+ );
312
+ }
313
+
314
+ const Icon = k.icon ? k.icon : 'div';
315
+
316
+ return (
317
+ <StyledIconButton
318
+ key={key}
319
+ tabIndex={'-1'}
320
+ onClick={onClick}
321
+ disabled={disabled}
322
+ category={category}
323
+ size="large"
324
+ {...extra}
325
+ >
326
+ <Icon className="icon" />
327
+ </StyledIconButton>
328
+ );
329
+ })}
330
+ </KeyPadContainer>
331
+ );
332
+ }
333
+ }
334
+
335
+ export default KeyPad;
@@ -0,0 +1,16 @@
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
+ };
@@ -0,0 +1,32 @@
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
+ });
@@ -0,0 +1,5 @@
1
+ export const DELETE = '\u232B';
2
+ export const LEFT_ARROW = '◀';
3
+ export const RIGHT_ARROW = '▶';
4
+ export const DIVIDE = '\u00F7';
5
+ export const MULTIPLY = '\u00D7';
@@ -0,0 +1,28 @@
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
+ });
@@ -0,0 +1,35 @@
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
+ });
@@ -0,0 +1,40 @@
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
+ );
@@ -0,0 +1,3 @@
1
+ import { DELETE } from './chars';
2
+
3
+ export const del = { label: DELETE, category: 'edit', keystroke: 'Backspace', ariaLabel: 'Delete' };
@@ -0,0 +1,28 @@
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
+ });
@@ -0,0 +1,26 @@
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
+ });
@@ -0,0 +1,144 @@
1
+ const set = (o) => ({ ...o, category: 'geometry' });
2
+
3
+ export const overline = set({
4
+ name: 'Line',
5
+ latex: '\\overline{}',
6
+ command: '\\overline',
7
+ });
8
+
9
+ export const overRightArrow = set({
10
+ name: 'Ray',
11
+ latex: '\\overrightarrow{}',
12
+ command: '\\overrightarrow',
13
+ });
14
+
15
+ export const overLeftRightArrow = set({
16
+ name: 'Segment',
17
+ latex: '\\overleftrightarrow{\\overline{}}', // used this notation to display the pink box
18
+ symbol: 'AB',
19
+ command: '\\overleftrightarrow',
20
+ });
21
+
22
+ export const segment = set({
23
+ name: 'Segment',
24
+ latex: '\\overleftrightarrow{AB}',
25
+ write: '\\overleftrightarrow{AB}',
26
+ label: 'AB',
27
+ });
28
+
29
+ export const parallel = set({
30
+ name: 'Parallel',
31
+ latex: '\\parallel',
32
+ command: '\\parallel',
33
+ });
34
+
35
+ export const notParallel = set({
36
+ name: 'Not Parallel',
37
+ latex: '\\nparallel',
38
+ command: '\\nparallel',
39
+ });
40
+
41
+ export const perpindicular = set({
42
+ name: 'Perpendicular',
43
+ latex: '\\perp',
44
+ command: '\\perpendicular',
45
+ });
46
+
47
+ export const angle = set({
48
+ name: 'Angle',
49
+ latex: '\\angle',
50
+ command: '\\angle',
51
+ });
52
+ export const overArc = set({
53
+ name: 'Over arc',
54
+ latex: '\\overarc{\\overline{}}', // used this notation to display the pink box
55
+ command: '\\overarc',
56
+ });
57
+ export const measureOfAngle = set({
58
+ name: 'Measured Angle',
59
+ latex: '\\measuredangle',
60
+ command: ['m', '\\angle'],
61
+ });
62
+
63
+ export const triangle = set({
64
+ name: 'Triangle',
65
+ latex: '\\triangle',
66
+ command: '\\triangle',
67
+ });
68
+
69
+ export const square = set({
70
+ name: 'Square',
71
+ latex: '\\square',
72
+ command: '\\square',
73
+ });
74
+
75
+ export const parallelogram = set({
76
+ name: 'Parallelogram',
77
+ latex: '\\parallelogram',
78
+ command: '\\parallelogram',
79
+ });
80
+
81
+ export const circledDot = set({
82
+ name: 'Circled Dot',
83
+ latex: '\\odot',
84
+ command: '\\odot',
85
+ });
86
+
87
+ export const degree = set({
88
+ name: 'Degree',
89
+ latex: '\\degree',
90
+ command: '\\degree',
91
+ });
92
+
93
+ export const similarTo = set({
94
+ name: 'Similar',
95
+ command: '\\sim',
96
+ latex: '\\sim',
97
+ });
98
+
99
+ export const congruentTo = set({
100
+ name: 'Congruent To',
101
+ command: '\\cong',
102
+ latex: '\\cong',
103
+ });
104
+
105
+ export const notCongruentTo = set({
106
+ name: 'Not Congruent To',
107
+ command: '\\ncong',
108
+ latex: '\\ncong',
109
+ });
110
+
111
+ export const primeArcminute = set({
112
+ name: 'Prime',
113
+ label: 'pam',
114
+ // eslint-disable-next-line
115
+ latex: "'",
116
+ // eslint-disable-next-line
117
+ write: "'",
118
+ });
119
+
120
+ export const doublePrimeArcSecond = set({
121
+ name: 'Double Prime',
122
+ // eslint-disable-next-line
123
+ latex: "''",
124
+ // eslint-disable-next-line
125
+ write: "''",
126
+ });
127
+
128
+ export const leftArrow = set({
129
+ name: 'Left Arrow',
130
+ latex: '\\leftarrow',
131
+ command: '\\leftarrow',
132
+ });
133
+
134
+ export const rightArrow = set({
135
+ name: 'Right Arrow',
136
+ latex: '\\rightarrow',
137
+ command: '\\rightarrow',
138
+ });
139
+
140
+ export const leftrightArrow = set({
141
+ name: 'Left and Right Arrow',
142
+ latex: '\\leftrightarrow',
143
+ command: '\\leftrightarrow',
144
+ });