@khanacademy/perseus 11.6.1 → 12.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.
- package/CHANGELOG.md +18 -0
- package/dist/components/math-input.d.ts +38 -11
- package/dist/components/tex-buttons.d.ts +2 -1
- package/dist/es/index.css +5 -6
- package/dist/es/index.js +999 -919
- package/dist/es/index.js.map +1 -1
- package/dist/index.css +5 -6
- package/dist/index.js +976 -895
- package/dist/index.js.map +1 -1
- package/dist/perseus-types.d.ts +2 -1
- package/dist/strings.js +3 -0
- package/dist/widgets/expression.d.ts +15 -14
- package/package.json +2 -2
- package/src/__tests__/mock-asset-loading-widget.tsx +1 -2
- package/src/components/__stories__/math-input.stories.tsx +17 -4
- package/src/components/__tests__/math-input.test.tsx +95 -8
- package/src/components/math-input.tsx +274 -96
- package/src/components/tex-buttons.tsx +2 -2
- package/src/perseus-types.ts +11 -1
- package/src/styles/perseus-renderer.less +5 -6
- package/src/styles/widgets/expression.less +0 -6
- package/src/widgets/__stories__/expression.stories.tsx +3 -3
- package/src/widgets/__tests__/expression.test.tsx +4 -77
- package/src/widgets/expression.tsx +99 -94
- package/tsconfig-build.tsbuildinfo +1 -1
package/dist/es/index.js
CHANGED
|
@@ -1,33 +1,33 @@
|
|
|
1
1
|
import * as KAS from '@khanacademy/kas';
|
|
2
|
-
import { keyTranslator, createMathField, mathQuillInstance, KeypadInput, KeypadType, keypadElementPropType, MobileKeypad } from '@khanacademy/math-input';
|
|
2
|
+
import { keyTranslator, CursorContext, createMathField, mathQuillInstance, getCursorContext, DesktopKeypad, KeypadInput, KeypadType, KeyArray, keypadElementPropType, MobileKeypad } from '@khanacademy/math-input';
|
|
3
3
|
import * as PerseusLinter from '@khanacademy/perseus-linter';
|
|
4
4
|
import { linterContextDefault, Rule, linterContextProps } from '@khanacademy/perseus-linter';
|
|
5
|
+
import { View, RenderStateRoot, Text } from '@khanacademy/wonder-blocks-core';
|
|
5
6
|
import * as i18n from '@khanacademy/wonder-blocks-i18n';
|
|
7
|
+
import Tooltip$1 from '@khanacademy/wonder-blocks-tooltip';
|
|
6
8
|
import classNames from 'classnames';
|
|
7
9
|
import * as React from 'react';
|
|
8
10
|
import { useState, useEffect, useRef } from 'react';
|
|
9
11
|
import _, { debounce } from 'underscore';
|
|
12
|
+
import Clickable from '@khanacademy/wonder-blocks-clickable';
|
|
13
|
+
import Color, { fade } from '@khanacademy/wonder-blocks-color';
|
|
14
|
+
import { Popover, PopoverContentCore, PopoverContent } from '@khanacademy/wonder-blocks-popover';
|
|
15
|
+
import Spacing from '@khanacademy/wonder-blocks-spacing';
|
|
16
|
+
import { StyleSheet, css } from 'aphrodite';
|
|
10
17
|
import $ from 'jquery';
|
|
18
|
+
import PropTypes from 'prop-types';
|
|
11
19
|
import * as ReactDOM from 'react-dom';
|
|
12
20
|
import ReactDOM__default from 'react-dom';
|
|
13
|
-
import PropTypes from 'prop-types';
|
|
14
21
|
import { number, point, vector as vector$1, line, ray } from '@khanacademy/kmath';
|
|
15
|
-
import Spacing from '@khanacademy/wonder-blocks-spacing';
|
|
16
|
-
import { StyleSheet, css } from 'aphrodite';
|
|
17
22
|
import { CircularSpinner } from '@khanacademy/wonder-blocks-progress-spinner';
|
|
18
|
-
import { RenderStateRoot, View, Text } from '@khanacademy/wonder-blocks-core';
|
|
19
23
|
import SimpleMarkdown from '@khanacademy/simple-markdown';
|
|
20
24
|
import { pureMarkdownRules } from '@khanacademy/pure-markdown';
|
|
21
25
|
import { TextField } from '@khanacademy/wonder-blocks-form';
|
|
22
26
|
import Button from '@khanacademy/wonder-blocks-button';
|
|
23
|
-
import Clickable from '@khanacademy/wonder-blocks-clickable';
|
|
24
|
-
import Color from '@khanacademy/wonder-blocks-color';
|
|
25
27
|
import { Strut } from '@khanacademy/wonder-blocks-layout';
|
|
26
|
-
import { Popover, PopoverContent, PopoverContentCore } from '@khanacademy/wonder-blocks-popover';
|
|
27
28
|
import { OptionItem, SingleSelect } from '@khanacademy/wonder-blocks-dropdown';
|
|
28
29
|
import debounce$1 from 'lodash.debounce';
|
|
29
30
|
import createReactClass from 'create-react-class';
|
|
30
|
-
import Tooltip$1 from '@khanacademy/wonder-blocks-tooltip';
|
|
31
31
|
import Link from '@khanacademy/wonder-blocks-link';
|
|
32
32
|
import { addLibraryVersionToPerseusDebug } from '@khanacademy/perseus-core';
|
|
33
33
|
|
|
@@ -49,317 +49,6 @@ function _extends() {
|
|
|
49
49
|
return _extends.apply(this, arguments);
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
/**
|
|
53
|
-
* A stripped version of Icon.jsx from webapp. Takes an SVG icon and renders it
|
|
54
|
-
* inline like Font Awesome did.
|
|
55
|
-
*
|
|
56
|
-
* If you are looking for an icon that we've used before you should look in
|
|
57
|
-
* webapp's `icon-paths.js` which is a reference file for all the SVG paths
|
|
58
|
-
* that we've used. You'll need to copy the object from that file into
|
|
59
|
-
* whichever file you're using the icon and explicitly pass it in to the
|
|
60
|
-
* <InlineIcon/> React component.
|
|
61
|
-
*
|
|
62
|
-
* We assume that the viewBox is cropped and aligned to (0, 0), but icons can
|
|
63
|
-
* be defined differently. At some point we might want to add these attributes
|
|
64
|
-
* to `icon-paths.js`, but for now this is a fairly safe assumption.
|
|
65
|
-
*
|
|
66
|
-
* Sample usage:
|
|
67
|
-
*
|
|
68
|
-
* const editIcon = {
|
|
69
|
-
* path: "M41.209 53.753l5.39 0l0 5.39l3.136 0l6.468-6.517-8.477-8.526-6.517 6.517l0 3.136zm33.173-34.937q-.882-.882-1.862.049l-19.6 19.6q-.931.98-.049 1.862t1.862-.049l19.6-19.6q.931-.98.049-1.862zm-38.563 45.668l0-16.121l37.632-37.632 16.17 16.121-37.632 37.632l-16.17 0zm43.022-12.397l0 10.633q-.049 6.713-4.753 11.417t-11.368 4.704l-46.599 0q-6.713 0-11.417-4.753t-4.704-11.368l0-46.599q0-6.664 4.753-11.417t11.368-4.704l46.599 0q3.528 0 6.566 1.372.833.392.98 1.323t-.49 1.617l-2.744 2.744q-.784.784-1.96.441t-2.352-.343l-46.599 0q-3.675 0-6.321 2.646t-2.646 6.321l0 46.599q0 3.675 2.646 6.321t6.321 2.646l46.599 0q3.675 0 6.321-2.646t2.646-6.321l0-7.056q0-.735.49-1.225l3.577-3.577q.833-.833 1.96-.392t1.127 1.617zm7.203-51.646q2.254 0 3.773 1.568l8.526 8.526q1.568 1.568 1.568 3.822t-1.568 3.773l-5.145 5.145-16.121-16.121 5.145-5.145q1.568-1.568 3.822-1.568z",
|
|
70
|
-
* width: 100,
|
|
71
|
-
* height: 78.912,
|
|
72
|
-
* };
|
|
73
|
-
* <InlineIcon {...editIcon} />
|
|
74
|
-
*
|
|
75
|
-
*/
|
|
76
|
-
const InlineIcon = ({
|
|
77
|
-
path,
|
|
78
|
-
width,
|
|
79
|
-
height,
|
|
80
|
-
style: _style = {},
|
|
81
|
-
title
|
|
82
|
-
}) => /*#__PURE__*/React.createElement("svg", {
|
|
83
|
-
role: "img",
|
|
84
|
-
"aria-hidden": !title,
|
|
85
|
-
style: _extends({
|
|
86
|
-
verticalAlign: "middle"
|
|
87
|
-
}, _style),
|
|
88
|
-
width: `${width / height}em`,
|
|
89
|
-
height: "1em",
|
|
90
|
-
viewBox: `0 0 ${width} ${height}`
|
|
91
|
-
}, !!title && /*#__PURE__*/React.createElement("title", null, title), /*#__PURE__*/React.createElement("path", {
|
|
92
|
-
d: path,
|
|
93
|
-
fill: "currentColor"
|
|
94
|
-
}));
|
|
95
|
-
|
|
96
|
-
let _dependencies = null;
|
|
97
|
-
const setDependencies = dependencies => {
|
|
98
|
-
_dependencies = dependencies;
|
|
99
|
-
};
|
|
100
|
-
const getDependencies = () => {
|
|
101
|
-
if (_dependencies) {
|
|
102
|
-
return _dependencies;
|
|
103
|
-
}
|
|
104
|
-
throw new Error(["Perseus has not been provided required dependencies.", "setDependencies(dependencies) must be called first.", "Make sure Perseus is being imported from javascript/perseus/perseus.js."].join("\n"));
|
|
105
|
-
};
|
|
106
|
-
const DependenciesContext = /*#__PURE__*/React.createContext({
|
|
107
|
-
analytics: {
|
|
108
|
-
onAnalyticsEvent: async () => {}
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* useDependencies provides easy access to the current Perseus dependencies.
|
|
114
|
-
*/
|
|
115
|
-
const useDependencies = () => {
|
|
116
|
-
const deps = React.useContext(DependenciesContext);
|
|
117
|
-
return deps;
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
var dependencies = /*#__PURE__*/Object.freeze({
|
|
121
|
-
__proto__: null,
|
|
122
|
-
setDependencies: setDependencies,
|
|
123
|
-
getDependencies: getDependencies,
|
|
124
|
-
DependenciesContext: DependenciesContext,
|
|
125
|
-
useDependencies: useDependencies
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
129
|
-
const prettyBig = {
|
|
130
|
-
fontSize: "150%"
|
|
131
|
-
};
|
|
132
|
-
const slightlyBig = {
|
|
133
|
-
fontSize: "120%"
|
|
134
|
-
};
|
|
135
|
-
const symbStyle = {
|
|
136
|
-
fontSize: "130%"
|
|
137
|
-
};
|
|
138
|
-
// These are functions because we want to generate a new component for each use
|
|
139
|
-
// on the page rather than reusing an instance (which will cause an error).
|
|
140
|
-
// Also, it's useful for things which might look different depending on the
|
|
141
|
-
// props.
|
|
142
|
-
|
|
143
|
-
const basic = [() => [/*#__PURE__*/React.createElement("span", {
|
|
144
|
-
key: "plus",
|
|
145
|
-
style: slightlyBig
|
|
146
|
-
}, "+"), "PLUS", i18n._("Plus")], () => [/*#__PURE__*/React.createElement("span", {
|
|
147
|
-
key: "minus",
|
|
148
|
-
style: prettyBig
|
|
149
|
-
}, "-"), "MINUS", i18n._("Minus")],
|
|
150
|
-
// TODO(joel) - display as \cdot when appropriate
|
|
151
|
-
props => {
|
|
152
|
-
const {
|
|
153
|
-
TeX
|
|
154
|
-
} = getDependencies();
|
|
155
|
-
if (props.convertDotToTimes) {
|
|
156
|
-
return [/*#__PURE__*/React.createElement(TeX, {
|
|
157
|
-
key: "times",
|
|
158
|
-
style: prettyBig
|
|
159
|
-
}, i18n.doNotTranslate("\\times")), "TIMES", i18n._("Multiply")];
|
|
160
|
-
}
|
|
161
|
-
return [/*#__PURE__*/React.createElement(TeX, {
|
|
162
|
-
key: "times",
|
|
163
|
-
style: prettyBig
|
|
164
|
-
}, i18n.doNotTranslate("\\cdot")), "CDOT", i18n._("Multiply")];
|
|
165
|
-
}, () => {
|
|
166
|
-
const {
|
|
167
|
-
TeX
|
|
168
|
-
} = getDependencies();
|
|
169
|
-
return [/*#__PURE__*/React.createElement(TeX, {
|
|
170
|
-
key: "frac",
|
|
171
|
-
style: prettyBig
|
|
172
|
-
}, i18n.doNotTranslate("\\frac{x}{y}")), "FRAC", i18n._("Fraction, excluding the current expression")];
|
|
173
|
-
}];
|
|
174
|
-
const buttonSets = {
|
|
175
|
-
basic,
|
|
176
|
-
"basic+div": basic.concat([() => {
|
|
177
|
-
const {
|
|
178
|
-
TeX
|
|
179
|
-
} = getDependencies();
|
|
180
|
-
return [/*#__PURE__*/React.createElement(TeX, {
|
|
181
|
-
key: "div"
|
|
182
|
-
}, i18n.doNotTranslate("\\div")), "DIVIDE", i18n._("Divide")];
|
|
183
|
-
}]),
|
|
184
|
-
trig: [() => {
|
|
185
|
-
const {
|
|
186
|
-
TeX
|
|
187
|
-
} = getDependencies();
|
|
188
|
-
return [/*#__PURE__*/React.createElement(TeX, {
|
|
189
|
-
key: "sin"
|
|
190
|
-
}, i18n.doNotTranslate("\\sin")), "SIN", i18n._("Sine")];
|
|
191
|
-
}, () => {
|
|
192
|
-
const {
|
|
193
|
-
TeX
|
|
194
|
-
} = getDependencies();
|
|
195
|
-
return [/*#__PURE__*/React.createElement(TeX, {
|
|
196
|
-
key: "cos"
|
|
197
|
-
}, i18n.doNotTranslate("\\cos")), "COS", i18n._("Cosine")];
|
|
198
|
-
}, () => {
|
|
199
|
-
const {
|
|
200
|
-
TeX
|
|
201
|
-
} = getDependencies();
|
|
202
|
-
return [/*#__PURE__*/React.createElement(TeX, {
|
|
203
|
-
key: "tan"
|
|
204
|
-
}, i18n.doNotTranslate("\\tan")), "TAN", i18n._("Tangent")];
|
|
205
|
-
}, () => {
|
|
206
|
-
const {
|
|
207
|
-
TeX
|
|
208
|
-
} = getDependencies();
|
|
209
|
-
return [/*#__PURE__*/React.createElement(TeX, {
|
|
210
|
-
key: "theta",
|
|
211
|
-
style: symbStyle
|
|
212
|
-
}, i18n.doNotTranslate("\\theta")), "THETA", i18n._("Theta")];
|
|
213
|
-
}, () => {
|
|
214
|
-
const {
|
|
215
|
-
TeX
|
|
216
|
-
} = getDependencies();
|
|
217
|
-
return [/*#__PURE__*/React.createElement("span", {
|
|
218
|
-
key: "phi"
|
|
219
|
-
}, /*#__PURE__*/React.createElement("span", {
|
|
220
|
-
className: "perseus-sr-only"
|
|
221
|
-
}, i18n.doNotTranslate("phi")), /*#__PURE__*/React.createElement(TeX, {
|
|
222
|
-
key: "pi",
|
|
223
|
-
style: symbStyle
|
|
224
|
-
}, i18n.doNotTranslate("\\phi"))), "PHI", i18n._("Phi")];
|
|
225
|
-
}],
|
|
226
|
-
prealgebra: [() => {
|
|
227
|
-
const {
|
|
228
|
-
TeX
|
|
229
|
-
} = getDependencies();
|
|
230
|
-
return [/*#__PURE__*/React.createElement(TeX, {
|
|
231
|
-
key: "sqrt"
|
|
232
|
-
}, i18n.doNotTranslate("\\sqrt{x}")), "SQRT", i18n._("Square root")];
|
|
233
|
-
},
|
|
234
|
-
// TODO(joel) - how does desmos do this?
|
|
235
|
-
() => {
|
|
236
|
-
const {
|
|
237
|
-
TeX
|
|
238
|
-
} = getDependencies();
|
|
239
|
-
return [/*#__PURE__*/React.createElement(TeX, {
|
|
240
|
-
key: "nthroot"
|
|
241
|
-
}, i18n.doNotTranslate("\\sqrt[3]{x}")), "NTHROOT3", i18n._("Cube root")];
|
|
242
|
-
}, () => {
|
|
243
|
-
const {
|
|
244
|
-
TeX
|
|
245
|
-
} = getDependencies();
|
|
246
|
-
return [/*#__PURE__*/React.createElement(TeX, {
|
|
247
|
-
key: "pow",
|
|
248
|
-
style: slightlyBig
|
|
249
|
-
}, i18n.doNotTranslate("a^b")), "POW", i18n._("Exponent")];
|
|
250
|
-
}, () => {
|
|
251
|
-
const {
|
|
252
|
-
TeX
|
|
253
|
-
} = getDependencies();
|
|
254
|
-
return [/*#__PURE__*/React.createElement(TeX, {
|
|
255
|
-
key: "pi",
|
|
256
|
-
style: slightlyBig
|
|
257
|
-
}, i18n.doNotTranslate("\\pi")), "PI", i18n._("Pi")];
|
|
258
|
-
}],
|
|
259
|
-
logarithms: [() => {
|
|
260
|
-
const {
|
|
261
|
-
TeX
|
|
262
|
-
} = getDependencies();
|
|
263
|
-
return [/*#__PURE__*/React.createElement(TeX, {
|
|
264
|
-
key: "log"
|
|
265
|
-
}, i18n.doNotTranslate("\\log")), "LOG", i18n._("Logarithm with base 10")];
|
|
266
|
-
}, () => {
|
|
267
|
-
const {
|
|
268
|
-
TeX
|
|
269
|
-
} = getDependencies();
|
|
270
|
-
return [/*#__PURE__*/React.createElement(TeX, {
|
|
271
|
-
key: "ln"
|
|
272
|
-
}, i18n.doNotTranslate("\\ln")), "LN", i18n._("Natural logarithm")];
|
|
273
|
-
}, () => {
|
|
274
|
-
const {
|
|
275
|
-
TeX
|
|
276
|
-
} = getDependencies();
|
|
277
|
-
return [/*#__PURE__*/React.createElement(TeX, {
|
|
278
|
-
key: "log_b"
|
|
279
|
-
}, i18n.doNotTranslate("\\log_b")), "LOG_B", i18n._("Logarithm with custom base")];
|
|
280
|
-
}],
|
|
281
|
-
"basic relations": [() => {
|
|
282
|
-
const {
|
|
283
|
-
TeX
|
|
284
|
-
} = getDependencies();
|
|
285
|
-
return [/*#__PURE__*/React.createElement(TeX, {
|
|
286
|
-
key: "eq"
|
|
287
|
-
}, "="), "EQUAL", i18n._("Equals sign")];
|
|
288
|
-
}, () => {
|
|
289
|
-
const {
|
|
290
|
-
TeX
|
|
291
|
-
} = getDependencies();
|
|
292
|
-
return [/*#__PURE__*/React.createElement(TeX, {
|
|
293
|
-
key: "lt"
|
|
294
|
-
}, i18n.doNotTranslate("\\lt")), "LT", i18n._("Less than sign")];
|
|
295
|
-
}, () => {
|
|
296
|
-
const {
|
|
297
|
-
TeX
|
|
298
|
-
} = getDependencies();
|
|
299
|
-
return [/*#__PURE__*/React.createElement(TeX, {
|
|
300
|
-
key: "gt"
|
|
301
|
-
}, i18n.doNotTranslate("\\gt")), "GT", i18n._("Greater than sign")];
|
|
302
|
-
}],
|
|
303
|
-
"advanced relations": [() => {
|
|
304
|
-
const {
|
|
305
|
-
TeX
|
|
306
|
-
} = getDependencies();
|
|
307
|
-
return [/*#__PURE__*/React.createElement(TeX, {
|
|
308
|
-
key: "neq"
|
|
309
|
-
}, i18n.doNotTranslate("\\neq")), "NEQ", i18n._("Not-equals sign")];
|
|
310
|
-
}, () => {
|
|
311
|
-
const {
|
|
312
|
-
TeX
|
|
313
|
-
} = getDependencies();
|
|
314
|
-
return [/*#__PURE__*/React.createElement(TeX, {
|
|
315
|
-
key: "leq"
|
|
316
|
-
}, i18n.doNotTranslate("\\leq")), "LEQ", i18n._("Less than or equal to sign")];
|
|
317
|
-
}, () => {
|
|
318
|
-
const {
|
|
319
|
-
TeX
|
|
320
|
-
} = getDependencies();
|
|
321
|
-
return [/*#__PURE__*/React.createElement(TeX, {
|
|
322
|
-
key: "geq"
|
|
323
|
-
}, i18n.doNotTranslate("\\geq")), "GEQ", i18n._("Greater than or equal to sign")];
|
|
324
|
-
}]
|
|
325
|
-
};
|
|
326
|
-
const buttonSetsPropType = PropTypes.arrayOf(PropTypes.oneOf(_(buttonSets).keys()));
|
|
327
|
-
class TexButtons extends React.Component {
|
|
328
|
-
render() {
|
|
329
|
-
// Always show buttonSets in the same order. Note: Technically it's ok
|
|
330
|
-
// for _.keys() to return the keys in an arbitrary order, but in
|
|
331
|
-
// practice, they will be ordered as listed above.
|
|
332
|
-
const sortedButtonSets = _.sortBy(this.props.sets, setName =>
|
|
333
|
-
// @ts-expect-error - TS2345 - Argument of type 'string | number' is not assignable to parameter of type 'string'.
|
|
334
|
-
_.keys(buttonSets).indexOf(setName));
|
|
335
|
-
const buttons = _(sortedButtonSets).map(setName => buttonSets[setName]);
|
|
336
|
-
const buttonRows = _(buttons).map(row => row.map(symbGen => {
|
|
337
|
-
// create a (component, thing we should send to mathquill) pair
|
|
338
|
-
const symbol = symbGen(this.props);
|
|
339
|
-
return /*#__PURE__*/React.createElement("button", {
|
|
340
|
-
onClick: () => this.props.onInsert(symbol[1]),
|
|
341
|
-
className: "tex-button"
|
|
342
|
-
// @ts-expect-error - TS2533 - Object is possibly 'null' or 'undefined'. | TS2339 - Property 'key' does not exist on type 'boolean | ReactChild | ReactFragment | ReactPortal'.
|
|
343
|
-
,
|
|
344
|
-
key: symbol[0].key,
|
|
345
|
-
type: "button",
|
|
346
|
-
"aria-label": symbol[2]
|
|
347
|
-
}, symbol[0]);
|
|
348
|
-
}));
|
|
349
|
-
const buttonPopup = _(buttonRows).map((row, i) => {
|
|
350
|
-
return /*#__PURE__*/React.createElement("div", {
|
|
351
|
-
className: "clearfix tex-button-row",
|
|
352
|
-
key: this.props.sets[i]
|
|
353
|
-
}, row);
|
|
354
|
-
});
|
|
355
|
-
return /*#__PURE__*/React.createElement("div", {
|
|
356
|
-
className: `${this.props.className || ""} preview-measure`
|
|
357
|
-
}, buttonPopup);
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
TexButtons.buttonSets = buttonSets;
|
|
361
|
-
TexButtons.buttonSetsType = buttonSetsPropType;
|
|
362
|
-
|
|
363
52
|
const customKeyTranslator = _extends({}, keyTranslator, {
|
|
364
53
|
// If there's something in the input that can become part of a
|
|
365
54
|
// fraction, typing "/" puts it in the numerator. If not, typing
|
|
@@ -381,57 +70,9 @@ class MathInput extends React.Component {
|
|
|
381
70
|
this.__mathFieldWrapperRef = null;
|
|
382
71
|
this.__mathField = null;
|
|
383
72
|
this.state = {
|
|
384
|
-
focused: false
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
this.setState({
|
|
388
|
-
focused: true
|
|
389
|
-
});
|
|
390
|
-
// TODO(joel) fix properly - we should probably allow onFocus handlers
|
|
391
|
-
// to this property, but we need to work correctly with them.
|
|
392
|
-
// if (this.props.onFocus) {
|
|
393
|
-
// this.props.onFocus();
|
|
394
|
-
// }
|
|
395
|
-
};
|
|
396
|
-
this.handleMouseDown = event => {
|
|
397
|
-
// @ts-expect-error - TS2531 - Object is possibly 'null'. | TS2345 - Argument of type 'EventTarget | null' is not assignable to parameter of type 'Node | null'.
|
|
398
|
-
const focused = ReactDOM__default.findDOMNode(this).contains(event.target);
|
|
399
|
-
this.mouseDown = focused;
|
|
400
|
-
if (!focused) {
|
|
401
|
-
this.setState({
|
|
402
|
-
focused: false
|
|
403
|
-
});
|
|
404
|
-
}
|
|
405
|
-
};
|
|
406
|
-
this.handleMouseUp = () => {
|
|
407
|
-
// this mouse click started in the buttons div so we should focus the
|
|
408
|
-
// input
|
|
409
|
-
if (this.mouseDown) {
|
|
410
|
-
this.focus();
|
|
411
|
-
}
|
|
412
|
-
this.mouseDown = false;
|
|
413
|
-
};
|
|
414
|
-
this.handleBlur = e => {
|
|
415
|
-
// TODO(michaelpolyak): Consider trapping focus within the button group.
|
|
416
|
-
// Focusing back on the input when TAB out of the last button in the
|
|
417
|
-
// group. This will probably require ESCAPE key handling to enable to
|
|
418
|
-
// close (blur) the button group in order to focus on next page element.
|
|
419
|
-
if (!this.mouseDown &&
|
|
420
|
-
// @ts-expect-error - TS2531 - Object is possibly 'null'.
|
|
421
|
-
!ReactDOM__default.findDOMNode(this).contains(e.relatedTarget)) {
|
|
422
|
-
this.setState({
|
|
423
|
-
focused: false
|
|
424
|
-
});
|
|
425
|
-
}
|
|
426
|
-
};
|
|
427
|
-
this._shouldShowButtons = () => {
|
|
428
|
-
if (this.props.buttonsVisible === "always") {
|
|
429
|
-
return true;
|
|
430
|
-
}
|
|
431
|
-
if (this.props.buttonsVisible === "never") {
|
|
432
|
-
return false;
|
|
433
|
-
}
|
|
434
|
-
return this.state.focused;
|
|
73
|
+
focused: false,
|
|
74
|
+
keypadOpen: this.props.buttonsVisible === "always" ? true : false,
|
|
75
|
+
cursorContext: CursorContext.NONE
|
|
435
76
|
};
|
|
436
77
|
this.insert = value => {
|
|
437
78
|
const input = this.mathField();
|
|
@@ -493,6 +134,9 @@ class MathInput extends React.Component {
|
|
|
493
134
|
if (this.props.value !== value) {
|
|
494
135
|
this.props.onChange(value);
|
|
495
136
|
}
|
|
137
|
+
this.setState({
|
|
138
|
+
cursorContext: getCursorContext(mathField)
|
|
139
|
+
});
|
|
496
140
|
},
|
|
497
141
|
enter: () => {
|
|
498
142
|
// NOTE(kevinb): This isn't how answers to exercises are
|
|
@@ -525,479 +169,250 @@ class MathInput extends React.Component {
|
|
|
525
169
|
focused: true
|
|
526
170
|
});
|
|
527
171
|
};
|
|
528
|
-
this.blur = () => {
|
|
529
|
-
|
|
530
|
-
(_this$mathField2 = this.mathField()) == null ? void 0 : _this$mathField2.blur();
|
|
531
|
-
this.setState({
|
|
532
|
-
focused: false
|
|
533
|
-
});
|
|
534
|
-
};
|
|
535
|
-
}
|
|
536
|
-
componentDidMount() {
|
|
537
|
-
var _this$mathField3;
|
|
538
|
-
window.addEventListener("mousedown", this.handleMouseDown);
|
|
539
|
-
window.addEventListener("mouseup", this.handleMouseUp);
|
|
540
|
-
|
|
541
|
-
// Ideally, we would be able to pass an initial value directly into
|
|
542
|
-
// the constructor
|
|
543
|
-
(_this$mathField3 = this.mathField()) == null ? void 0 : _this$mathField3.latex(this.props.value);
|
|
544
|
-
}
|
|
545
|
-
componentWillUnmount() {
|
|
546
|
-
window.removeEventListener("mousedown", this.handleMouseDown);
|
|
547
|
-
window.removeEventListener("mouseup", this.handleMouseUp);
|
|
548
|
-
}
|
|
549
|
-
|
|
550
|
-
// handlers:
|
|
551
|
-
// keep track of two related bits of state:
|
|
552
|
-
// * this.state.focused - whether the buttons are currently shown
|
|
553
|
-
// * this.mouseDown - whether a mouse click is active that started in the
|
|
554
|
-
// buttons div
|
|
555
|
-
|
|
556
|
-
render() {
|
|
557
|
-
let className = classNames({
|
|
558
|
-
"perseus-math-input": true,
|
|
559
|
-
// mathquill usually adds these itself but react removes them when
|
|
560
|
-
// updating the component.
|
|
561
|
-
"mq-editable-field": true,
|
|
562
|
-
"mq-math-mode": true
|
|
172
|
+
this.blur = () => this.setState({
|
|
173
|
+
focused: false
|
|
563
174
|
});
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
onInsert: this.insert
|
|
575
|
-
});
|
|
576
|
-
}
|
|
577
|
-
return /*#__PURE__*/React.createElement("div", {
|
|
578
|
-
style: {
|
|
579
|
-
display: "inline-block"
|
|
580
|
-
}
|
|
581
|
-
}, /*#__PURE__*/React.createElement("div", {
|
|
582
|
-
style: {
|
|
583
|
-
display: "inline-block"
|
|
175
|
+
this.handleKeypadPress = (key, e) => {
|
|
176
|
+
const translator = keyTranslator[key];
|
|
177
|
+
const mathField = this.mathField();
|
|
178
|
+
if (mathField) {
|
|
179
|
+
if (translator) {
|
|
180
|
+
translator(mathField, key);
|
|
181
|
+
}
|
|
182
|
+
this.setState({
|
|
183
|
+
cursorContext: getCursorContext(mathField)
|
|
184
|
+
});
|
|
584
185
|
}
|
|
585
|
-
}, /*#__PURE__*/React.createElement("span", {
|
|
586
|
-
className: className,
|
|
587
|
-
ref: ref => this.__mathFieldWrapperRef = ref,
|
|
588
|
-
"aria-label": this.props.labelText,
|
|
589
|
-
onFocus: this.handleFocus,
|
|
590
|
-
onBlur: this.handleBlur
|
|
591
|
-
})), /*#__PURE__*/React.createElement("div", {
|
|
592
|
-
style: {
|
|
593
|
-
position: "relative"
|
|
594
|
-
},
|
|
595
|
-
onBlur: this.handleBlur
|
|
596
|
-
}, buttons));
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
MathInput.defaultProps = {
|
|
600
|
-
value: "",
|
|
601
|
-
convertDotToTimes: false,
|
|
602
|
-
buttonsVisible: "focused"
|
|
603
|
-
};
|
|
604
|
-
|
|
605
|
-
/* eslint-disable react/no-unsafe */
|
|
606
|
-
const zIndex = 10;
|
|
607
|
-
let HorizontalDirection = /*#__PURE__*/function (HorizontalDirection) {
|
|
608
|
-
HorizontalDirection["Left"] = "left";
|
|
609
|
-
HorizontalDirection["Right"] = "right";
|
|
610
|
-
return HorizontalDirection;
|
|
611
|
-
}({});
|
|
612
|
-
let VerticalDirection = /*#__PURE__*/function (VerticalDirection) {
|
|
613
|
-
VerticalDirection["Top"] = "top";
|
|
614
|
-
VerticalDirection["Bottom"] = "bottom";
|
|
615
|
-
return VerticalDirection;
|
|
616
|
-
}({});
|
|
617
|
-
const Triangle = props => {
|
|
618
|
-
let borderLeft;
|
|
619
|
-
let borderRight;
|
|
620
|
-
let borderTop;
|
|
621
|
-
let borderBottom;
|
|
622
|
-
const hBorder = `${props.width}px solid transparent`;
|
|
623
|
-
if (props.horizontalDirection === "right") {
|
|
624
|
-
borderLeft = hBorder;
|
|
625
|
-
} else {
|
|
626
|
-
borderRight = hBorder;
|
|
627
|
-
}
|
|
628
|
-
const vBorder = `${props.height}px solid ${props.color}`;
|
|
629
|
-
if (props.verticalDirection === "top") {
|
|
630
|
-
borderTop = vBorder;
|
|
631
|
-
} else {
|
|
632
|
-
borderBottom = vBorder;
|
|
633
|
-
}
|
|
634
|
-
return /*#__PURE__*/React.createElement("div", {
|
|
635
|
-
style: {
|
|
636
|
-
display: "block",
|
|
637
|
-
height: 0,
|
|
638
|
-
width: 0,
|
|
639
|
-
position: "absolute",
|
|
640
|
-
left: props.left,
|
|
641
|
-
top: props["top"],
|
|
642
|
-
borderLeft: borderLeft,
|
|
643
|
-
borderRight: borderRight,
|
|
644
|
-
borderTop: borderTop,
|
|
645
|
-
borderBottom: borderBottom
|
|
646
|
-
}
|
|
647
|
-
});
|
|
648
|
-
};
|
|
649
|
-
const TooltipArrow = props => {
|
|
650
|
-
// TODO(aria): Think about adding a box-shadow to the triangle here
|
|
651
|
-
// See http://css-tricks.com/triangle-with-shadow/
|
|
652
|
-
|
|
653
|
-
//const isRight = (this.props.horizontalDirection === "right");
|
|
654
|
-
const isTop = props.verticalDirection === "top";
|
|
655
|
-
const frontTopOffset = isTop ? 0 : 1;
|
|
656
|
-
const borderTopOffset = isTop ? 0 : -1;
|
|
657
|
-
return /*#__PURE__*/React.createElement("div", {
|
|
658
|
-
style: {
|
|
659
|
-
display: "block",
|
|
660
|
-
position: props.position,
|
|
661
|
-
visibility: props.visibility,
|
|
662
|
-
left: props.left,
|
|
663
|
-
top: props["top"],
|
|
664
|
-
width: props.width + 2,
|
|
665
|
-
height: props.height + 1,
|
|
666
|
-
marginTop: -1,
|
|
667
|
-
marginBottom: -2,
|
|
668
|
-
zIndex: zIndex
|
|
669
|
-
}
|
|
670
|
-
}, /*#__PURE__*/React.createElement(Triangle, {
|
|
671
|
-
horizontalDirection: props.horizontalDirection,
|
|
672
|
-
verticalDirection: props.verticalDirection,
|
|
673
|
-
color: props.border,
|
|
674
|
-
left: 0,
|
|
675
|
-
top: borderTopOffset,
|
|
676
|
-
width: props.width + 2 // one extra for the diagonal
|
|
677
|
-
,
|
|
678
|
-
height: props.height + 2
|
|
679
|
-
}), /*#__PURE__*/React.createElement(Triangle, {
|
|
680
|
-
horizontalDirection: props.horizontalDirection,
|
|
681
|
-
verticalDirection: props.verticalDirection,
|
|
682
|
-
color: props.color,
|
|
683
|
-
left: 1,
|
|
684
|
-
top: frontTopOffset,
|
|
685
|
-
width: props.width,
|
|
686
|
-
height: props.height
|
|
687
|
-
}));
|
|
688
|
-
};
|
|
689
|
-
TooltipArrow.defaultProps = {
|
|
690
|
-
position: "relative",
|
|
691
|
-
visibility: "visible",
|
|
692
|
-
left: 0,
|
|
693
|
-
top: 0
|
|
694
|
-
};
|
|
695
|
-
const VERTICAL_CORNERS = {
|
|
696
|
-
top: {
|
|
697
|
-
top: "-100%"
|
|
698
|
-
},
|
|
699
|
-
bottom: {
|
|
700
|
-
top: 0
|
|
701
|
-
}
|
|
702
|
-
};
|
|
703
|
-
const HORIZONTAL_CORNERS = {
|
|
704
|
-
left: {
|
|
705
|
-
targetLeft: 0
|
|
706
|
-
},
|
|
707
|
-
right: {
|
|
708
|
-
targetLeft: "100%"
|
|
709
|
-
}
|
|
710
|
-
};
|
|
711
|
-
const HORIZONTAL_ALIGNMNENTS = {
|
|
712
|
-
left: {
|
|
713
|
-
tooltipLeft: 0,
|
|
714
|
-
arrowLeft: arrowSize => 0
|
|
715
|
-
},
|
|
716
|
-
right: {
|
|
717
|
-
tooltipLeft: "-100%",
|
|
718
|
-
arrowLeft: arrowSize => -arrowSize - 2
|
|
719
|
-
}
|
|
720
|
-
};
|
|
721
|
-
class Tooltip extends React.Component {
|
|
722
|
-
constructor(...args) {
|
|
723
|
-
super(...args);
|
|
724
|
-
this.state = {
|
|
725
|
-
height: null // used for offsetting "top" positioned tooltips
|
|
726
|
-
};
|
|
727
|
-
}
|
|
728
186
|
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
});
|
|
737
|
-
}
|
|
738
|
-
componentDidUpdate() {
|
|
739
|
-
this._updateHeight();
|
|
740
|
-
}
|
|
741
|
-
_renderToolTipDiv(isTooltipAbove) {
|
|
742
|
-
const settings = Object.assign({}, HORIZONTAL_CORNERS[this.props.horizontalPosition], HORIZONTAL_ALIGNMNENTS[this.props.horizontalAlign], VERTICAL_CORNERS[this.props.verticalPosition]);
|
|
743
|
-
let arrowAbove;
|
|
744
|
-
let arrowBelow;
|
|
745
|
-
if (isTooltipAbove) {
|
|
746
|
-
// We put an absolutely positioned arrow in the correct place
|
|
747
|
-
arrowAbove = /*#__PURE__*/React.createElement(TooltipArrow, {
|
|
748
|
-
verticalDirection: VerticalDirection.Top,
|
|
749
|
-
horizontalDirection: this.props.horizontalAlign,
|
|
750
|
-
position: "absolute",
|
|
751
|
-
color: "white",
|
|
752
|
-
border: this.props.borderColor,
|
|
753
|
-
left: settings.arrowLeft(this.props.arrowSize),
|
|
754
|
-
top: -this.props.arrowSize + 2,
|
|
755
|
-
width: this.props.arrowSize,
|
|
756
|
-
height: this.props.arrowSize,
|
|
757
|
-
zIndex: zIndex
|
|
758
|
-
});
|
|
759
|
-
|
|
760
|
-
// And we use a visibility: hidden arrow below to shift up the
|
|
761
|
-
// content by the correct amount
|
|
762
|
-
arrowBelow = /*#__PURE__*/React.createElement(TooltipArrow, {
|
|
763
|
-
verticalDirection: VerticalDirection.Top,
|
|
764
|
-
horizontalDirection: this.props.horizontalAlign,
|
|
765
|
-
visibility: "hidden",
|
|
766
|
-
color: "white",
|
|
767
|
-
border: this.props.borderColor,
|
|
768
|
-
left: settings.arrowLeft(this.props.arrowSize),
|
|
769
|
-
top: -1,
|
|
770
|
-
width: this.props.arrowSize,
|
|
771
|
-
height: this.props.arrowSize,
|
|
772
|
-
zIndex: zIndex
|
|
773
|
-
});
|
|
774
|
-
} else {
|
|
775
|
-
arrowAbove = /*#__PURE__*/React.createElement(TooltipArrow, {
|
|
776
|
-
verticalDirection: VerticalDirection.Bottom,
|
|
777
|
-
horizontalDirection: this.props.horizontalAlign,
|
|
778
|
-
color: "white",
|
|
779
|
-
border: this.props.borderColor,
|
|
780
|
-
left: settings.arrowLeft(this.props.arrowSize),
|
|
781
|
-
top: -1,
|
|
782
|
-
width: this.props.arrowSize,
|
|
783
|
-
height: this.props.arrowSize,
|
|
784
|
-
zIndex: zIndex
|
|
785
|
-
});
|
|
786
|
-
arrowBelow = null;
|
|
787
|
-
}
|
|
788
|
-
|
|
789
|
-
/* A positioned div below the input to be the parent for our
|
|
790
|
-
tooltip */
|
|
791
|
-
return /*#__PURE__*/React.createElement("div", {
|
|
792
|
-
style: {
|
|
793
|
-
position: "relative",
|
|
794
|
-
height: 0,
|
|
795
|
-
display: this.props.show ? "block" : "none"
|
|
796
|
-
}
|
|
797
|
-
}, /*#__PURE__*/React.createElement("div", {
|
|
798
|
-
// eslint-disable-next-line react/no-string-refs
|
|
799
|
-
ref: "tooltipContainer",
|
|
800
|
-
className: "tooltipContainer",
|
|
801
|
-
style: {
|
|
802
|
-
position: "absolute",
|
|
803
|
-
// height must start out undefined, not null, so that
|
|
804
|
-
// we can measure the actual height with jquery.
|
|
805
|
-
// This is used to position the tooltip with top: -100%
|
|
806
|
-
// when in verticalPosition: "top" mode
|
|
807
|
-
height: this.state.height || undefined,
|
|
808
|
-
left: settings.targetLeft
|
|
809
|
-
}
|
|
810
|
-
}, arrowAbove, /*#__PURE__*/React.createElement("div", {
|
|
811
|
-
className: this.props.className
|
|
812
|
-
// eslint-disable-next-line react/no-string-refs
|
|
813
|
-
,
|
|
814
|
-
ref: "tooltipContent",
|
|
815
|
-
style: {
|
|
816
|
-
position: "relative",
|
|
817
|
-
top: settings["top"],
|
|
818
|
-
left: settings.tooltipLeft,
|
|
819
|
-
border: "1px solid " + this.props.borderColor,
|
|
820
|
-
boxShadow: "0 1px 3px " + this.props.borderColor,
|
|
821
|
-
zIndex: zIndex - 1
|
|
187
|
+
// We want to prevent taking focus from input when clicking on keypad
|
|
188
|
+
// Clickable handles "onClick" differently than react;
|
|
189
|
+
// a keyboard event is "keydown" type.
|
|
190
|
+
// In react without WonderBlocks, "enter" or "space" keydown events
|
|
191
|
+
// are also "click" events, differentiated by "detail".
|
|
192
|
+
if (e.type === "click") {
|
|
193
|
+
this.focus();
|
|
822
194
|
}
|
|
823
|
-
}
|
|
195
|
+
};
|
|
824
196
|
}
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
//
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
197
|
+
componentDidMount() {
|
|
198
|
+
var _this$mathField2;
|
|
199
|
+
// Ideally, we would be able to pass an initial value directly into
|
|
200
|
+
// the constructor
|
|
201
|
+
(_this$mathField2 = this.mathField()) == null ? void 0 : _this$mathField2.latex(this.props.value);
|
|
202
|
+
}
|
|
203
|
+
openKeypad() {
|
|
204
|
+
if (this.props.buttonsVisible === "never") {
|
|
205
|
+
return;
|
|
834
206
|
}
|
|
207
|
+
this.setState({
|
|
208
|
+
keypadOpen: true
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
closeKeypad() {
|
|
212
|
+
this.setState({
|
|
213
|
+
keypadOpen: false
|
|
214
|
+
});
|
|
835
215
|
}
|
|
836
216
|
render() {
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
217
|
+
let className = classNames({
|
|
218
|
+
"perseus-math-input": true,
|
|
219
|
+
// mathquill usually adds these itself but react removes them when
|
|
220
|
+
// updating the component.
|
|
221
|
+
"mq-editable-field": true,
|
|
222
|
+
"mq-math-mode": true
|
|
223
|
+
});
|
|
224
|
+
if (this.props.className) {
|
|
225
|
+
className = className + " " + this.props.className;
|
|
226
|
+
}
|
|
227
|
+
return /*#__PURE__*/React.createElement(View, {
|
|
228
|
+
style: [styles$A.outerWrapper, this.state.focused && styles$A.wrapperFocused, this.props.hasError && styles$A.wrapperError]
|
|
229
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
230
|
+
style: {
|
|
231
|
+
display: "flex",
|
|
232
|
+
padding: 1
|
|
233
|
+
},
|
|
234
|
+
onClick: () => {
|
|
235
|
+
const mathField = this.mathField();
|
|
236
|
+
if (!mathField) {
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
this.setState({
|
|
240
|
+
cursorContext: getCursorContext(mathField)
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
}, /*#__PURE__*/React.createElement("span", {
|
|
244
|
+
className: className,
|
|
245
|
+
ref: ref => this.__mathFieldWrapperRef = ref,
|
|
246
|
+
"aria-label": this.props.labelText,
|
|
247
|
+
onFocus: () => this.focus(),
|
|
248
|
+
onBlur: () => this.blur()
|
|
249
|
+
}), /*#__PURE__*/React.createElement(Popover, {
|
|
250
|
+
opened: this.state.keypadOpen,
|
|
251
|
+
onClose: () => this.closeKeypad(),
|
|
252
|
+
dismissEnabled: true,
|
|
253
|
+
content: () => {
|
|
254
|
+
var _this$props$keypadBut, _this$props;
|
|
255
|
+
return /*#__PURE__*/React.createElement(PopoverContentCore, {
|
|
256
|
+
closeButtonVisible: true,
|
|
257
|
+
style: styles$A.popoverContent
|
|
258
|
+
}, /*#__PURE__*/React.createElement(DesktopKeypad, _extends({
|
|
259
|
+
onAnalyticsEvent: this.props.analytics.onAnalyticsEvent,
|
|
260
|
+
extraKeys: this.props.extraKeys,
|
|
261
|
+
onClickKey: this.handleKeypadPress,
|
|
262
|
+
cursorContext: this.state.cursorContext,
|
|
263
|
+
convertDotToTimes: this.props.convertDotToTimes
|
|
264
|
+
}, (_this$props$keypadBut = this.props.keypadButtonSets) != null ? _this$props$keypadBut : mapButtonSets((_this$props = this.props) == null ? void 0 : _this$props.buttonSets))));
|
|
265
|
+
}
|
|
266
|
+
}, this.props.buttonsVisible === "never" ? /*#__PURE__*/React.createElement(MathInputIcon, {
|
|
267
|
+
hovered: false,
|
|
268
|
+
focused: false,
|
|
269
|
+
active: false
|
|
270
|
+
}) : /*#__PURE__*/React.createElement(Clickable, {
|
|
271
|
+
"aria-label": this.state.keypadOpen ? i18n._("close math keypad") : i18n._("open math keypad"),
|
|
272
|
+
"aria-checked": this.state.keypadOpen,
|
|
273
|
+
role: "switch",
|
|
274
|
+
onClick: () => this.state.keypadOpen ? this.closeKeypad() : this.openKeypad()
|
|
275
|
+
}, props => /*#__PURE__*/React.createElement(MathInputIcon, _extends({
|
|
276
|
+
active: this.state.keypadOpen
|
|
277
|
+
}, props))))));
|
|
843
278
|
}
|
|
844
279
|
}
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
className: "",
|
|
849
|
-
arrowSize: 10,
|
|
850
|
-
borderColor: "#ccc",
|
|
851
|
-
verticalPosition: VerticalDirection.Bottom,
|
|
852
|
-
horizontalPosition: HorizontalDirection.Left,
|
|
853
|
-
horizontalAlign: HorizontalDirection.Left,
|
|
854
|
-
targetContainerStyle: {}
|
|
855
|
-
};
|
|
856
|
-
|
|
857
|
-
/**
|
|
858
|
-
* Icon paths to be used with `inline-icon.jsx`.
|
|
859
|
-
*
|
|
860
|
-
* These paths are taken directly from webapp's `icon-paths.js`. Unlike the
|
|
861
|
-
* webapp equivalent, these can be directly required within Perseus files since
|
|
862
|
-
* this is all bundled together anyway.
|
|
863
|
-
*/
|
|
864
|
-
|
|
865
|
-
const iconCheck = {
|
|
866
|
-
path: `M8.70710678,12.2928932 C8.31658249,11.9023689 7.68341751,11.9023689 7.29289322,12.2928932 C6.90236893,12.6834175 6.90236893,13.3165825 7.29289322,13.7071068 L9.82842712,16.2426407 C10.2207367,16.6349502 10.8574274,16.6328935 11.2471942,16.2380576 L16.7116603,10.7025237 C17.0996535,10.3094846 17.0955629,9.67633279 16.7025237,9.28833966 C16.3094846,8.90034653 15.6763328,8.90443714 15.2883397,9.29747629 L10.5309507,14.1167372 L8.70710678,12.2928932 Z`,
|
|
867
|
-
width: 24,
|
|
868
|
-
height: 24
|
|
869
|
-
};
|
|
870
|
-
const iconCheckMedium = {
|
|
871
|
-
path: "M6.072 10.4l6.175-7.058a1 1 0 1 1 1.506 1.317L6.769 12.64a1 1 0 0 1-1.55-.054L2.203 8.604a1 1 0 1 1 1.594-1.208L6.072 10.4z",
|
|
872
|
-
width: 16,
|
|
873
|
-
height: 16
|
|
874
|
-
};
|
|
875
|
-
const iconChevronDown = {
|
|
876
|
-
path: "M99.669 13.048q0 3.36-2.352 5.712l-41.664 41.664q-2.408 2.408-5.88 2.408t-5.712-2.408l-41.664-41.664q-2.408-2.24-2.408-5.712t2.408-5.88l4.76-4.816q2.52-2.352 5.88-2.352t5.656 2.352l31.136 31.136 31.08-31.136q2.352-2.352 5.712-2.352t5.88 2.352l4.816 4.816q2.352 2.52 2.352 5.88z",
|
|
877
|
-
width: 100,
|
|
878
|
-
height: 63.034
|
|
879
|
-
};
|
|
880
|
-
const iconChevronRight = {
|
|
881
|
-
path: "M62.808 49.728q0 3.36-2.352 5.88l-41.72 41.664q-2.352 2.408-5.768 2.408t-5.768-2.408l-4.872-4.76q-2.352-2.52-2.352-5.88t2.352-5.712l31.08-31.136-31.08-31.024q-2.352-2.52-2.352-5.88t2.352-5.712l4.872-4.76q2.296-2.408 5.768-2.408t5.768 2.408l41.72 41.664q2.352 2.296 2.352 5.656z",
|
|
882
|
-
width: 63.034,
|
|
883
|
-
height: 100
|
|
884
|
-
};
|
|
885
|
-
const iconCircle = {
|
|
886
|
-
path: "M100.035 50.046q.057 13.623-6.669 25.137t-18.24 18.183-25.08 6.669-25.137-6.726q-11.514-6.726-18.183-18.183-6.726-11.571-6.726-25.137t6.726-25.08 18.24-18.24 25.08-6.669q13.566 0 25.08 6.726 11.514 6.669 18.24 18.183t6.669 25.137z",
|
|
887
|
-
width: 100,
|
|
888
|
-
height: 100
|
|
889
|
-
};
|
|
890
|
-
const iconCircleArrowDown = {
|
|
891
|
-
path: "M50.046 83.676q1.767 0 2.907-1.14l29.526-29.526q1.197-1.197 1.197-2.907t-1.197-2.964l-5.928-5.928q-1.197-1.14-2.964-1.14t-2.907 1.14l-12.312 12.312l0-32.661q0-1.71-1.254-2.964t-2.907-1.254l-8.322 0q-1.71 0-2.964 1.254t-1.254 2.964l0 32.661l-12.312-12.312q-1.197-1.254-2.907-1.254t-2.907 1.254l-5.928 5.928q-1.197 1.197-1.197 2.964t1.197 2.907l29.469 29.526q1.197 1.14 2.964 1.14zm49.989-33.63q.057 13.623-6.669 25.137t-18.24 18.183-25.08 6.669-25.137-6.726q-11.514-6.726-18.183-18.183-6.726-11.571-6.726-25.137t6.726-25.08 18.24-18.24 25.08-6.669q13.566 0 25.08 6.726 11.514 6.669 18.24 18.183t6.669 25.137z",
|
|
892
|
-
width: 100,
|
|
893
|
-
height: 100
|
|
894
|
-
};
|
|
895
|
-
const iconCircleArrowUp = {
|
|
896
|
-
path: "M54.207 83.391q1.653 0 2.907-1.254t1.254-2.907l0-32.718l12.312 12.312q1.254 1.254 2.964 1.254t2.907-1.254l5.928-5.928q1.197-1.197 1.14-2.964 0-1.767-1.14-2.907l-29.526-29.526q-1.197-1.14-2.907-1.14t-2.964 1.14l-29.469 29.526q-1.197 1.254-1.197 2.964t1.197 2.907l5.928 5.928q1.197 1.197 2.907 1.197t2.907-1.197l12.312-12.312l0 32.718q0 1.653 1.254 2.907t2.964 1.254l8.322 0zm45.828-33.345q.057 13.623-6.669 25.137t-18.24 18.183-25.08 6.669-25.137-6.726q-11.514-6.726-18.183-18.183-6.726-11.571-6.726-25.137t6.726-25.08 18.24-18.24 25.08-6.669q13.566 0 25.08 6.726 11.514 6.669 18.24 18.183t6.669 25.137z",
|
|
897
|
-
width: 100,
|
|
898
|
-
height: 100
|
|
899
|
-
};
|
|
900
|
-
const iconCircleThin = {
|
|
901
|
-
path: "M50.046 8.322q-8.493 0-16.188 3.306-15.561 6.669-22.173 22.23-3.363 7.695-3.363 16.188t3.306 16.188 8.949 13.281q5.586 5.586 13.281 8.892t16.188 3.306 16.188-3.306 13.281-8.892 8.892-13.281 3.306-16.188-3.306-16.188-8.892-13.281-13.281-8.949q-7.695-3.306-16.188-3.306zm0 91.713q-13.623 0-25.137-6.726t-18.183-18.183q-6.726-11.571-6.726-25.137t6.726-25.08 18.24-18.24 25.08-6.669q13.566 0 25.08 6.726 11.514 6.669 18.24 18.183t6.726 25.137-6.726 25.137-18.24 18.126q-11.514 6.726-25.08 6.726z",
|
|
902
|
-
width: 100,
|
|
903
|
-
height: 99.944
|
|
904
|
-
};
|
|
905
|
-
const iconDesktop = {
|
|
906
|
-
path: "M94.208 52.119l0-43.746q0-.69-.506-1.15t-1.196-.506l-84.088 0q-.69 0-1.196.506t-.506 1.15l0 43.746q0 .69.506 1.196t1.196.506l84.088 0q.69 0 1.196-.506t.506-1.196zm6.716-43.746l0 57.224q0 3.45-2.484 5.934t-5.934 2.484l-28.566 0q0 3.128 2.53 7.774.828 1.61.828 2.622t-1.012 2.07q-1.012 1.012-2.346.966l-26.91 0q-1.38 0-2.392-1.012t-1.012-2.024q0-1.058 1.656-4.14t1.748-6.256l-28.612 0q-3.45 0-5.934-2.484t-2.484-5.934l0-57.224q0-3.45 2.484-5.934t5.934-2.438l84.088 0q3.45 0 5.98 2.438 2.438 2.484 2.438 5.934z",
|
|
907
|
-
width: 100,
|
|
908
|
-
height: 86.648
|
|
909
|
-
};
|
|
910
|
-
const iconDropdownArrow = {
|
|
911
|
-
path: "M9 9.8c0 .5.7 1.7 1.5 2.8 1.5 1.9 1.5 1.9 3 0C15.7 9.7 15.4 9 12 9c-1.6 0-3 .4-3 .8z",
|
|
912
|
-
width: 24,
|
|
913
|
-
height: 24
|
|
914
|
-
};
|
|
915
|
-
const iconExclamationSign = {
|
|
916
|
-
path: "M58.368 81.225l0-12.369q0-.912-.57-1.539t-1.425-.627l-12.54 0q-.855-.057-1.482.627t-.684 1.539l0 12.369q-.057.855.627 1.482t1.539.684l12.54 0q.855 0 1.425-.627t.57-1.539zm1.026-62.871q0-1.596-2.223-1.71l-14.307 0q-2.109 0-2.223 1.71l1.14 40.47q0 .627.627 1.14t1.539.456l12.084 0q.912-.057 1.539-.513t.684-1.083zm-9.348-18.354q13.566 0 25.08 6.726 11.514 6.669 18.24 18.183t6.726 25.137-6.726 25.137-18.24 18.183-25.08 6.669-25.137-6.726q-11.514-6.726-18.183-18.183-6.726-11.571-6.726-25.137t6.726-25.08 18.24-18.24 25.08-6.669z",
|
|
917
|
-
width: 100,
|
|
918
|
-
height: 99.944
|
|
919
|
-
};
|
|
920
|
-
// Grabbed from https://github.com/encharm/Font-Awesome-SVG-PNG
|
|
921
|
-
const iconGear = {
|
|
922
|
-
path: "M1152 896q0-106-75-181t-181-75-181 75-75 181 75 181 181 75 181-75 75-181zm512-109v222q0 12-8 23t-20 13l-185 28q-19 54-39 91 35 50 107 138 10 12 10 25t-9 23q-27 37-99 108t-94 71q-12 0-26-9l-138-108q-44 23-91 38-16 136-29 186-7 28-36 28h-222q-14 0-24.5-8.5t-11.5-21.5l-28-184q-49-16-90-37l-141 107q-10 9-25 9-14 0-25-11-126-114-165-168-7-10-7-23 0-12 8-23 15-21 51-66.5t54-70.5q-27-50-41-99l-183-27q-13-2-21-12.5t-8-23.5v-222q0-12 8-23t19-13l186-28q14-46 39-92-40-57-107-138-10-12-10-24 0-10 9-23 26-36 98.5-107.5t94.5-71.5q13 0 26 10l138 107q44-23 91-38 16-136 29-186 7-28 36-28h222q14 0 24.5 8.5t11.5 21.5l28 184q49 16 90 37l142-107q9-9 24-9 13 0 25 10 129 119 165 170 7 8 7 22 0 12-8 23-15 21-51 66.5t-54 70.5q26 50 41 98l183 28q13 2 21 12.5t8 23.5z",
|
|
923
|
-
width: 1792,
|
|
924
|
-
height: 1792
|
|
925
|
-
};
|
|
926
|
-
const iconMobilePhone = {
|
|
927
|
-
path: "M36.04 89.557q0-2.584-1.836-4.42t-4.42-1.836-4.352 1.836q-1.836 1.836-1.836 4.42t1.836 4.352 4.42 1.836q2.652-.068 4.42-1.836t1.768-4.352zm16.184-12.444l0-54.74q0-1.088-.748-1.768t-1.768-.68l-39.78 0q-1.088 0-1.768.748t-.68 1.7l0 54.74q0 1.02.748 1.768t1.7.68l39.78 0q1.02-.068 1.768-.748t.748-1.7zm-14.892-65.892q0-1.224-1.292-1.292l-12.444 0q-1.224.068-1.224 1.292t1.224 1.224l12.444 0q1.292 0 1.292-1.224zm22.372-1.292l0 79.628q0 3.944-2.992 6.936t-7.004 2.992l-39.78 0q-4.012 0-7.004-2.924-2.924-2.924-2.924-7.004l0-79.628q0-4.012 2.924-6.936t7.004-2.992l39.78 0q4.012-.068 7.004 2.924t2.992 7.004z",
|
|
928
|
-
width: 60.013,
|
|
929
|
-
height: 100
|
|
930
|
-
};
|
|
931
|
-
const iconOk = {
|
|
932
|
-
path: "M37.964 76.048q-2.576 0-4.368-1.792l-31.864-31.864q-1.792-1.792-1.792-4.368t1.792-4.368l8.736-8.68q1.792-1.792 4.368-1.792t4.312 1.792l18.816 18.872 42-42.056q1.792-1.792 4.368-1.792t4.312 1.792l8.736 8.736q1.792 1.792 1.792 4.368t-1.792 4.312l-55.048 55.048q-1.792 1.792-4.368 1.792z",
|
|
933
|
-
width: 100,
|
|
934
|
-
height: 76.637
|
|
935
|
-
};
|
|
936
|
-
const iconPlus = {
|
|
937
|
-
path: "M99.758 43.09l0 13.578q0 2.852-1.984 4.836t-4.836 1.984l-29.45 0l0 29.45q0 2.852-1.984 4.836t-4.836 1.984l-13.578 0q-2.852 0-4.836-1.984t-1.984-4.836l0-29.45l-29.45 0q-2.852 0-4.836-1.984t-1.984-4.836l0-13.578q0-2.852 1.984-4.836t4.836-1.984l29.45 0l0-29.45q0-2.852 1.984-4.836t4.836-1.984l13.578 0q2.852 0 4.836 1.984t1.984 4.836l0 29.45l29.45 0q2.852 0 4.836 1.984t1.984 4.836z",
|
|
938
|
-
width: 100,
|
|
939
|
-
height: 100
|
|
940
|
-
};
|
|
941
|
-
const iconRemove = {
|
|
942
|
-
path: "M100.464 80.808q0 3.404-2.368 5.772l-11.47 11.544q-2.368 2.368-5.772 2.368t-5.698-2.368l-24.864-24.864-24.864 24.864q-2.368 2.368-5.772 2.368t-5.772-2.368l-11.47-11.544q-2.368-2.368-2.368-5.772t2.368-5.698l24.864-24.864-24.864-24.864q-2.368-2.368-2.368-5.772t2.368-5.772l11.47-11.47q2.368-2.368 5.772-2.368t5.772 2.368l24.864 24.864 24.864-24.864q2.294-2.368 5.698-2.368t5.772 2.368l11.47 11.47q2.368 2.368 2.368 5.772t-2.368 5.772l-24.864 24.864 24.864 24.864q2.368 2.294 2.368 5.698z",
|
|
943
|
-
width: 100,
|
|
944
|
-
height: 100
|
|
280
|
+
MathInput.defaultProps = {
|
|
281
|
+
value: "",
|
|
282
|
+
convertDotToTimes: false
|
|
945
283
|
};
|
|
946
|
-
const
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
284
|
+
const MathInputIcon = ({
|
|
285
|
+
hovered,
|
|
286
|
+
focused,
|
|
287
|
+
active
|
|
288
|
+
}) => {
|
|
289
|
+
let color;
|
|
290
|
+
switch (true) {
|
|
291
|
+
case focused || active:
|
|
292
|
+
color = Color.white;
|
|
293
|
+
break;
|
|
294
|
+
case hovered:
|
|
295
|
+
color = Color.blue;
|
|
296
|
+
break;
|
|
297
|
+
default:
|
|
298
|
+
color = Color.offBlack;
|
|
299
|
+
break;
|
|
300
|
+
}
|
|
301
|
+
const dynamicClass = active || focused ? styles$A.iconActive : styles$A.iconInactive;
|
|
302
|
+
return /*#__PURE__*/React.createElement(View, {
|
|
303
|
+
style: [styles$A.iconContainer, dynamicClass]
|
|
304
|
+
}, /*#__PURE__*/React.createElement("svg", {
|
|
305
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
306
|
+
width: "16",
|
|
307
|
+
height: "16",
|
|
308
|
+
fill: color,
|
|
309
|
+
viewBox: "0 0 256 256"
|
|
310
|
+
}, /*#__PURE__*/React.createElement("path", {
|
|
311
|
+
d: "M112,72a8,8,0,0,1-8,8H40a8,8,0,0,1,0-16h64A8,8,0,0,1,112,72Zm-8,104H80V152a8,8,0,0,0-16,0v24H40a8,8,0,0,0,0,16H64v24a8,8,0,0,0,16,0V192h24a8,8,0,0,0,0-16Zm48,0h64a8,8,0,0,0,0-16H152a8,8,0,0,0,0,16Zm64,16H152a8,8,0,0,0,0,16h64a8,8,0,0,0,0-16Zm-61.66-90.34a8,8,0,0,0,11.32,0L184,83.31l18.34,18.35a8,8,0,0,0,11.32-11.32L195.31,72l18.35-18.34a8,8,0,0,0-11.32-11.32L184,60.69,165.66,42.34a8,8,0,0,0-11.32,11.32L172.69,72,154.34,90.34A8,8,0,0,0,154.34,101.66Z"
|
|
312
|
+
})));
|
|
950
313
|
};
|
|
951
|
-
const
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
314
|
+
const mapButtonSets = buttonSets => {
|
|
315
|
+
const keypadButtonSets = {};
|
|
316
|
+
if (!buttonSets) {
|
|
317
|
+
return keypadButtonSets;
|
|
318
|
+
}
|
|
319
|
+
buttonSets.forEach(buttonSet => {
|
|
320
|
+
switch (buttonSet) {
|
|
321
|
+
case "advanced relations":
|
|
322
|
+
keypadButtonSets.advancedRelations = true;
|
|
323
|
+
break;
|
|
324
|
+
case "basic relations":
|
|
325
|
+
keypadButtonSets.basicRelations = true;
|
|
326
|
+
break;
|
|
327
|
+
case "basic+div":
|
|
328
|
+
keypadButtonSets.divisionKey = true;
|
|
329
|
+
break;
|
|
330
|
+
case "logarithms":
|
|
331
|
+
keypadButtonSets.logarithms = true;
|
|
332
|
+
break;
|
|
333
|
+
case "prealgebra":
|
|
334
|
+
keypadButtonSets.preAlgebra = true;
|
|
335
|
+
break;
|
|
336
|
+
case "trig":
|
|
337
|
+
keypadButtonSets.trigonometry = true;
|
|
338
|
+
break;
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
return keypadButtonSets;
|
|
955
342
|
};
|
|
956
|
-
const
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
343
|
+
const inputFocused = {
|
|
344
|
+
borderWidth: 2,
|
|
345
|
+
borderColor: Color.blue,
|
|
346
|
+
margin: -1
|
|
960
347
|
};
|
|
961
|
-
const
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
348
|
+
const styles$A = StyleSheet.create({
|
|
349
|
+
iconContainer: {
|
|
350
|
+
display: "flex",
|
|
351
|
+
justifyContent: "center",
|
|
352
|
+
height: "100%",
|
|
353
|
+
padding: Spacing.xxxSmall_4,
|
|
354
|
+
borderRadius: 1
|
|
355
|
+
},
|
|
356
|
+
iconInactive: {
|
|
357
|
+
backgroundColor: Color.offBlack8
|
|
358
|
+
},
|
|
359
|
+
iconActive: {
|
|
360
|
+
backgroundColor: Color.offBlack64
|
|
361
|
+
},
|
|
362
|
+
outerWrapper: {
|
|
363
|
+
display: "inline-block",
|
|
364
|
+
borderStyle: "solid",
|
|
365
|
+
borderWidth: 1,
|
|
366
|
+
borderColor: Color.offBlack50,
|
|
367
|
+
borderRadius: 3,
|
|
368
|
+
background: Color.white,
|
|
369
|
+
":hover": inputFocused
|
|
370
|
+
},
|
|
371
|
+
wrapperFocused: inputFocused,
|
|
372
|
+
wrapperError: {
|
|
373
|
+
borderColor: Color.red,
|
|
374
|
+
background: fade(Color.red, 0.08),
|
|
375
|
+
":hover": {
|
|
376
|
+
borderColor: Color.red
|
|
377
|
+
}
|
|
378
|
+
},
|
|
379
|
+
popoverContent: {
|
|
380
|
+
padding: 0,
|
|
381
|
+
paddingBottom: Spacing.xxSmall_6,
|
|
382
|
+
maxWidth: "initial"
|
|
383
|
+
}
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
let _dependencies = null;
|
|
387
|
+
const setDependencies = dependencies => {
|
|
388
|
+
_dependencies = dependencies;
|
|
965
389
|
};
|
|
966
|
-
const
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
390
|
+
const getDependencies = () => {
|
|
391
|
+
if (_dependencies) {
|
|
392
|
+
return _dependencies;
|
|
393
|
+
}
|
|
394
|
+
throw new Error(["Perseus has not been provided required dependencies.", "setDependencies(dependencies) must be called first.", "Make sure Perseus is being imported from javascript/perseus/perseus.js."].join("\n"));
|
|
970
395
|
};
|
|
971
|
-
const
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
396
|
+
const DependenciesContext = /*#__PURE__*/React.createContext({
|
|
397
|
+
analytics: {
|
|
398
|
+
onAnalyticsEvent: async () => {}
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* useDependencies provides easy access to the current Perseus dependencies.
|
|
404
|
+
*/
|
|
405
|
+
const useDependencies = () => {
|
|
406
|
+
const deps = React.useContext(DependenciesContext);
|
|
407
|
+
return deps;
|
|
975
408
|
};
|
|
976
409
|
|
|
977
|
-
var
|
|
410
|
+
var dependencies = /*#__PURE__*/Object.freeze({
|
|
978
411
|
__proto__: null,
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
iconCircle: iconCircle,
|
|
984
|
-
iconCircleArrowDown: iconCircleArrowDown,
|
|
985
|
-
iconCircleArrowUp: iconCircleArrowUp,
|
|
986
|
-
iconCircleThin: iconCircleThin,
|
|
987
|
-
iconDesktop: iconDesktop,
|
|
988
|
-
iconDropdownArrow: iconDropdownArrow,
|
|
989
|
-
iconExclamationSign: iconExclamationSign,
|
|
990
|
-
iconGear: iconGear,
|
|
991
|
-
iconMobilePhone: iconMobilePhone,
|
|
992
|
-
iconOk: iconOk,
|
|
993
|
-
iconPlus: iconPlus,
|
|
994
|
-
iconRemove: iconRemove,
|
|
995
|
-
iconStar: iconStar,
|
|
996
|
-
iconTryAgain: iconTryAgain,
|
|
997
|
-
iconTablet: iconTablet,
|
|
998
|
-
iconTrash: iconTrash,
|
|
999
|
-
iconUndo: iconUndo,
|
|
1000
|
-
iconMinus: iconMinus
|
|
412
|
+
setDependencies: setDependencies,
|
|
413
|
+
getDependencies: getDependencies,
|
|
414
|
+
DependenciesContext: DependenciesContext,
|
|
415
|
+
useDependencies: useDependencies
|
|
1001
416
|
});
|
|
1002
417
|
|
|
1003
418
|
// TODO(LP-11481): Change the primary API we use for logging in Perseus to use
|
|
@@ -1521,6 +936,26 @@ const ClassNames = {
|
|
|
1521
936
|
MOBILE: "perseus-mobile"
|
|
1522
937
|
};
|
|
1523
938
|
|
|
939
|
+
/*
|
|
940
|
+
* A11y (Accessibility) style rules
|
|
941
|
+
* These are used to mark up areas on the site that should only be readable
|
|
942
|
+
* when using a screen reader.
|
|
943
|
+
*/
|
|
944
|
+
var a11y = StyleSheet.create({
|
|
945
|
+
// Make content only visible to screen readers.
|
|
946
|
+
// Both collegeboard.org and Bootstrap 3 use this exact implementation.
|
|
947
|
+
srOnly: {
|
|
948
|
+
border: 0,
|
|
949
|
+
clip: "rect(0,0,0,0)",
|
|
950
|
+
height: 1,
|
|
951
|
+
margin: -1,
|
|
952
|
+
overflow: "hidden",
|
|
953
|
+
padding: 0,
|
|
954
|
+
position: "absolute",
|
|
955
|
+
width: 1
|
|
956
|
+
}
|
|
957
|
+
});
|
|
958
|
+
|
|
1524
959
|
const KhanMath = {
|
|
1525
960
|
// Simplify formulas before display
|
|
1526
961
|
cleanMath: function (expr) {
|
|
@@ -2435,6 +1870,7 @@ const KhanAnswerTypes = {
|
|
|
2435
1870
|
}
|
|
2436
1871
|
};
|
|
2437
1872
|
|
|
1873
|
+
const ERROR_TITLE = i18n._("Oops!");
|
|
2438
1874
|
const ERROR_MESSAGE = i18n._("Sorry, I don't understand that!");
|
|
2439
1875
|
const insertBraces = value => {
|
|
2440
1876
|
// HACK(alex): Make sure that all LaTeX super/subscripts are wrapped
|
|
@@ -2469,53 +1905,48 @@ class Expression extends React.Component {
|
|
|
2469
1905
|
constructor(..._args) {
|
|
2470
1906
|
super(..._args);
|
|
2471
1907
|
this._isMounted = false;
|
|
2472
|
-
this.errorTimeout = null;
|
|
2473
1908
|
this.displayName = "Expression";
|
|
2474
1909
|
this.state = {
|
|
1910
|
+
invalid: false,
|
|
2475
1911
|
showErrorTooltip: false,
|
|
2476
|
-
|
|
1912
|
+
showErrorStyle: false
|
|
2477
1913
|
};
|
|
2478
1914
|
this.componentDidMount = () => {
|
|
1915
|
+
document.addEventListener("mousedown", this._handleMouseDown);
|
|
1916
|
+
|
|
2479
1917
|
// TODO(scottgrant): This is a hack to remove the deprecated call to
|
|
2480
1918
|
// this.isMounted() but is still considered an anti-pattern.
|
|
2481
1919
|
this._isMounted = true;
|
|
2482
1920
|
};
|
|
2483
1921
|
this.componentDidUpdate = prevProps => {
|
|
2484
1922
|
if (!_.isEqual(this.props.value, prevProps.value) || !_.isEqual(this.props.functions, prevProps.functions)) {
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
this.
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
this.errorTimeout = setTimeout(() => {
|
|
2500
|
-
const apiResult = this.props.apiOptions.onInputError(null,
|
|
2501
|
-
// reserved for some widget identifier
|
|
2502
|
-
this.props.value, ERROR_MESSAGE);
|
|
2503
|
-
if (apiResult !== false) {
|
|
2504
|
-
this.setState({
|
|
2505
|
-
showErrorTooltip: true
|
|
2506
|
-
});
|
|
2507
|
-
}
|
|
2508
|
-
}, 2000);
|
|
1923
|
+
this.setState({
|
|
1924
|
+
invalid: false,
|
|
1925
|
+
showErrorTooltip: false,
|
|
1926
|
+
showErrorStyle: false
|
|
1927
|
+
});
|
|
1928
|
+
if (!this.parse(this.props.value, this.props).parsed) {
|
|
1929
|
+
const apiResult = this.props.apiOptions.onInputError(null,
|
|
1930
|
+
// reserved for some widget identifier
|
|
1931
|
+
this.props.value, ERROR_MESSAGE);
|
|
1932
|
+
if (apiResult !== false) {
|
|
1933
|
+
this.setState({
|
|
1934
|
+
invalid: true
|
|
1935
|
+
});
|
|
1936
|
+
}
|
|
2509
1937
|
}
|
|
2510
1938
|
}
|
|
2511
1939
|
};
|
|
2512
1940
|
this.componentWillUnmount = () => {
|
|
2513
|
-
// TODO(jeff, CP-3128): Use Wonder Blocks Timing API.
|
|
2514
|
-
// eslint-disable-next-line no-restricted-syntax
|
|
2515
|
-
// @ts-expect-error - TS2769 - No overload matches this call.
|
|
2516
|
-
clearTimeout(this.errorTimeout);
|
|
2517
1941
|
this._isMounted = false;
|
|
2518
1942
|
};
|
|
1943
|
+
this._handleMouseDown = () => {
|
|
1944
|
+
if (this._isMounted && this.state.showErrorTooltip) {
|
|
1945
|
+
this.setState({
|
|
1946
|
+
showErrorTooltip: false
|
|
1947
|
+
});
|
|
1948
|
+
}
|
|
1949
|
+
};
|
|
2519
1950
|
this.simpleValidate = (rubric, onInputError) => {
|
|
2520
1951
|
onInputError = onInputError || function () {};
|
|
2521
1952
|
const result = Expression.validate(this.getUserInput(), rubric, onInputError);
|
|
@@ -2542,7 +1973,8 @@ class Expression extends React.Component {
|
|
|
2542
1973
|
this.props.trackInteraction();
|
|
2543
1974
|
};
|
|
2544
1975
|
this._handleFocus = () => {
|
|
2545
|
-
|
|
1976
|
+
var _this$props$analytics;
|
|
1977
|
+
(_this$props$analytics = this.props.analytics) == null ? void 0 : _this$props$analytics.onAnalyticsEvent({
|
|
2546
1978
|
type: "perseus:expression-focused",
|
|
2547
1979
|
payload: null
|
|
2548
1980
|
});
|
|
@@ -2751,7 +2183,8 @@ class Expression extends React.Component {
|
|
|
2751
2183
|
this.refs.input.insert(keyPressed);
|
|
2752
2184
|
}
|
|
2753
2185
|
sendExpressionEvaluatedEvent(result) {
|
|
2754
|
-
|
|
2186
|
+
var _this$props$analytics2;
|
|
2187
|
+
(_this$props$analytics2 = this.props.analytics) == null ? void 0 : _this$props$analytics2.onAnalyticsEvent({
|
|
2755
2188
|
type: "perseus:expression-evaluated",
|
|
2756
2189
|
payload: {
|
|
2757
2190
|
result,
|
|
@@ -2760,6 +2193,7 @@ class Expression extends React.Component {
|
|
|
2760
2193
|
});
|
|
2761
2194
|
}
|
|
2762
2195
|
render() {
|
|
2196
|
+
var _this$props$keypadCon, _this$props$analytics3;
|
|
2763
2197
|
if (this.props.apiOptions.customKeypad) {
|
|
2764
2198
|
return /*#__PURE__*/React.createElement(KeypadInput
|
|
2765
2199
|
// eslint-disable-next-line react/no-string-refs
|
|
@@ -2782,47 +2216,27 @@ class Expression extends React.Component {
|
|
|
2782
2216
|
onBlur: this._handleBlur
|
|
2783
2217
|
});
|
|
2784
2218
|
}
|
|
2785
|
-
// TODO(alex): Style this tooltip to be more consistent with other
|
|
2786
|
-
// tooltips on the site; align to left middle (once possible)
|
|
2787
|
-
const errorTooltip = /*#__PURE__*/React.createElement("span", {
|
|
2788
|
-
className: "error-tooltip",
|
|
2789
|
-
role: "tooltip"
|
|
2790
|
-
}, /*#__PURE__*/React.createElement(Tooltip, {
|
|
2791
|
-
className: "error-text-container",
|
|
2792
|
-
horizontalPosition: HorizontalDirection.Right,
|
|
2793
|
-
horizontalAlign: HorizontalDirection.Left,
|
|
2794
|
-
verticalPosition: VerticalDirection.Top,
|
|
2795
|
-
arrowSize: 10,
|
|
2796
|
-
borderColor: "#fcc335",
|
|
2797
|
-
show: this.state.showErrorText
|
|
2798
|
-
}, /*#__PURE__*/React.createElement("span", {
|
|
2799
|
-
className: "error-icon",
|
|
2800
|
-
"data-test-id": "test-error-icon",
|
|
2801
|
-
onMouseEnter: () => {
|
|
2802
|
-
this.setState({
|
|
2803
|
-
showErrorText: true
|
|
2804
|
-
});
|
|
2805
|
-
},
|
|
2806
|
-
onMouseLeave: () => {
|
|
2807
|
-
this.setState({
|
|
2808
|
-
showErrorText: false
|
|
2809
|
-
});
|
|
2810
|
-
},
|
|
2811
|
-
onClick: () => {
|
|
2812
|
-
// TODO(alex): Better error feedback for mobile
|
|
2813
|
-
this.setState({
|
|
2814
|
-
showErrorText: !this.state.showErrorText
|
|
2815
|
-
});
|
|
2816
|
-
}
|
|
2817
|
-
}, /*#__PURE__*/React.createElement(InlineIcon, iconExclamationSign)), /*#__PURE__*/React.createElement("div", {
|
|
2818
|
-
className: "error-text"
|
|
2819
|
-
}, ERROR_MESSAGE)));
|
|
2820
2219
|
const className = classNames({
|
|
2821
2220
|
"perseus-widget-expression": true,
|
|
2822
2221
|
"show-error-tooltip": this.state.showErrorTooltip
|
|
2823
2222
|
});
|
|
2824
2223
|
return /*#__PURE__*/React.createElement("div", {
|
|
2825
|
-
className: className
|
|
2224
|
+
className: className,
|
|
2225
|
+
onBlur: () => this.state.invalid && this.setState({
|
|
2226
|
+
showErrorTooltip: true,
|
|
2227
|
+
showErrorStyle: true
|
|
2228
|
+
}),
|
|
2229
|
+
onFocus: () => this.setState({
|
|
2230
|
+
showErrorTooltip: false
|
|
2231
|
+
})
|
|
2232
|
+
}, /*#__PURE__*/React.createElement(View, {
|
|
2233
|
+
style: a11y.srOnly,
|
|
2234
|
+
role: "alert"
|
|
2235
|
+
}, this.state.showErrorTooltip && ERROR_TITLE + " " + ERROR_MESSAGE), /*#__PURE__*/React.createElement(Tooltip$1, {
|
|
2236
|
+
forceAnchorFocusivity: false,
|
|
2237
|
+
opened: this.state.showErrorTooltip,
|
|
2238
|
+
title: ERROR_TITLE,
|
|
2239
|
+
content: ERROR_MESSAGE
|
|
2826
2240
|
}, /*#__PURE__*/React.createElement(MathInput
|
|
2827
2241
|
// eslint-disable-next-line react/no-string-refs
|
|
2828
2242
|
, {
|
|
@@ -2831,11 +2245,15 @@ class Expression extends React.Component {
|
|
|
2831
2245
|
value: this.props.value,
|
|
2832
2246
|
onChange: this.changeAndTrack,
|
|
2833
2247
|
convertDotToTimes: this.props.times,
|
|
2834
|
-
buttonsVisible: this.props.buttonsVisible || "focused",
|
|
2835
2248
|
buttonSets: this.props.buttonSets,
|
|
2836
2249
|
onFocus: this._handleFocus,
|
|
2837
|
-
onBlur: this._handleBlur
|
|
2838
|
-
|
|
2250
|
+
onBlur: this._handleBlur,
|
|
2251
|
+
hasError: this.state.showErrorStyle,
|
|
2252
|
+
extraKeys: (_this$props$keypadCon = this.props.keypadConfiguration) == null ? void 0 : _this$props$keypadCon.extraKeys,
|
|
2253
|
+
analytics: (_this$props$analytics3 = this.props.analytics) != null ? _this$props$analytics3 : {
|
|
2254
|
+
onAnalyticsEvent: async function () {}
|
|
2255
|
+
}
|
|
2256
|
+
})));
|
|
2839
2257
|
}
|
|
2840
2258
|
}
|
|
2841
2259
|
|
|
@@ -2878,11 +2296,18 @@ const keypadConfigurationForProps = widgetOptions => {
|
|
|
2878
2296
|
// and Theta, so we special-case.
|
|
2879
2297
|
const isGreek = symbol => symbol === "pi" || symbol === "theta";
|
|
2880
2298
|
const toKey = symbol => isGreek(symbol) ? symbol.toUpperCase() : symbol;
|
|
2299
|
+
const isKey = key => KeyArray.includes(key);
|
|
2881
2300
|
for (const variable of expr.getVars()) {
|
|
2882
|
-
|
|
2301
|
+
const maybeKey = toKey(variable);
|
|
2302
|
+
if (isKey(maybeKey)) {
|
|
2303
|
+
uniqueExtraVariables[maybeKey] = true;
|
|
2304
|
+
}
|
|
2883
2305
|
}
|
|
2884
2306
|
for (const constant of expr.getConsts()) {
|
|
2885
|
-
|
|
2307
|
+
const maybeKey = toKey(constant);
|
|
2308
|
+
if (isKey(maybeKey)) {
|
|
2309
|
+
uniqueExtraConstants[maybeKey] = true;
|
|
2310
|
+
}
|
|
2886
2311
|
}
|
|
2887
2312
|
}
|
|
2888
2313
|
}
|
|
@@ -14949,6 +14374,196 @@ _.extend(MovableLine$4.prototype, {
|
|
|
14949
14374
|
}
|
|
14950
14375
|
});
|
|
14951
14376
|
|
|
14377
|
+
/**
|
|
14378
|
+
* A stripped version of Icon.jsx from webapp. Takes an SVG icon and renders it
|
|
14379
|
+
* inline like Font Awesome did.
|
|
14380
|
+
*
|
|
14381
|
+
* If you are looking for an icon that we've used before you should look in
|
|
14382
|
+
* webapp's `icon-paths.js` which is a reference file for all the SVG paths
|
|
14383
|
+
* that we've used. You'll need to copy the object from that file into
|
|
14384
|
+
* whichever file you're using the icon and explicitly pass it in to the
|
|
14385
|
+
* <InlineIcon/> React component.
|
|
14386
|
+
*
|
|
14387
|
+
* We assume that the viewBox is cropped and aligned to (0, 0), but icons can
|
|
14388
|
+
* be defined differently. At some point we might want to add these attributes
|
|
14389
|
+
* to `icon-paths.js`, but for now this is a fairly safe assumption.
|
|
14390
|
+
*
|
|
14391
|
+
* Sample usage:
|
|
14392
|
+
*
|
|
14393
|
+
* const editIcon = {
|
|
14394
|
+
* path: "M41.209 53.753l5.39 0l0 5.39l3.136 0l6.468-6.517-8.477-8.526-6.517 6.517l0 3.136zm33.173-34.937q-.882-.882-1.862.049l-19.6 19.6q-.931.98-.049 1.862t1.862-.049l19.6-19.6q.931-.98.049-1.862zm-38.563 45.668l0-16.121l37.632-37.632 16.17 16.121-37.632 37.632l-16.17 0zm43.022-12.397l0 10.633q-.049 6.713-4.753 11.417t-11.368 4.704l-46.599 0q-6.713 0-11.417-4.753t-4.704-11.368l0-46.599q0-6.664 4.753-11.417t11.368-4.704l46.599 0q3.528 0 6.566 1.372.833.392.98 1.323t-.49 1.617l-2.744 2.744q-.784.784-1.96.441t-2.352-.343l-46.599 0q-3.675 0-6.321 2.646t-2.646 6.321l0 46.599q0 3.675 2.646 6.321t6.321 2.646l46.599 0q3.675 0 6.321-2.646t2.646-6.321l0-7.056q0-.735.49-1.225l3.577-3.577q.833-.833 1.96-.392t1.127 1.617zm7.203-51.646q2.254 0 3.773 1.568l8.526 8.526q1.568 1.568 1.568 3.822t-1.568 3.773l-5.145 5.145-16.121-16.121 5.145-5.145q1.568-1.568 3.822-1.568z",
|
|
14395
|
+
* width: 100,
|
|
14396
|
+
* height: 78.912,
|
|
14397
|
+
* };
|
|
14398
|
+
* <InlineIcon {...editIcon} />
|
|
14399
|
+
*
|
|
14400
|
+
*/
|
|
14401
|
+
const InlineIcon = ({
|
|
14402
|
+
path,
|
|
14403
|
+
width,
|
|
14404
|
+
height,
|
|
14405
|
+
style: _style = {},
|
|
14406
|
+
title
|
|
14407
|
+
}) => /*#__PURE__*/React.createElement("svg", {
|
|
14408
|
+
role: "img",
|
|
14409
|
+
"aria-hidden": !title,
|
|
14410
|
+
style: _extends({
|
|
14411
|
+
verticalAlign: "middle"
|
|
14412
|
+
}, _style),
|
|
14413
|
+
width: `${width / height}em`,
|
|
14414
|
+
height: "1em",
|
|
14415
|
+
viewBox: `0 0 ${width} ${height}`
|
|
14416
|
+
}, !!title && /*#__PURE__*/React.createElement("title", null, title), /*#__PURE__*/React.createElement("path", {
|
|
14417
|
+
d: path,
|
|
14418
|
+
fill: "currentColor"
|
|
14419
|
+
}));
|
|
14420
|
+
|
|
14421
|
+
/**
|
|
14422
|
+
* Icon paths to be used with `inline-icon.jsx`.
|
|
14423
|
+
*
|
|
14424
|
+
* These paths are taken directly from webapp's `icon-paths.js`. Unlike the
|
|
14425
|
+
* webapp equivalent, these can be directly required within Perseus files since
|
|
14426
|
+
* this is all bundled together anyway.
|
|
14427
|
+
*/
|
|
14428
|
+
|
|
14429
|
+
const iconCheck = {
|
|
14430
|
+
path: `M8.70710678,12.2928932 C8.31658249,11.9023689 7.68341751,11.9023689 7.29289322,12.2928932 C6.90236893,12.6834175 6.90236893,13.3165825 7.29289322,13.7071068 L9.82842712,16.2426407 C10.2207367,16.6349502 10.8574274,16.6328935 11.2471942,16.2380576 L16.7116603,10.7025237 C17.0996535,10.3094846 17.0955629,9.67633279 16.7025237,9.28833966 C16.3094846,8.90034653 15.6763328,8.90443714 15.2883397,9.29747629 L10.5309507,14.1167372 L8.70710678,12.2928932 Z`,
|
|
14431
|
+
width: 24,
|
|
14432
|
+
height: 24
|
|
14433
|
+
};
|
|
14434
|
+
const iconCheckMedium = {
|
|
14435
|
+
path: "M6.072 10.4l6.175-7.058a1 1 0 1 1 1.506 1.317L6.769 12.64a1 1 0 0 1-1.55-.054L2.203 8.604a1 1 0 1 1 1.594-1.208L6.072 10.4z",
|
|
14436
|
+
width: 16,
|
|
14437
|
+
height: 16
|
|
14438
|
+
};
|
|
14439
|
+
const iconChevronDown = {
|
|
14440
|
+
path: "M99.669 13.048q0 3.36-2.352 5.712l-41.664 41.664q-2.408 2.408-5.88 2.408t-5.712-2.408l-41.664-41.664q-2.408-2.24-2.408-5.712t2.408-5.88l4.76-4.816q2.52-2.352 5.88-2.352t5.656 2.352l31.136 31.136 31.08-31.136q2.352-2.352 5.712-2.352t5.88 2.352l4.816 4.816q2.352 2.52 2.352 5.88z",
|
|
14441
|
+
width: 100,
|
|
14442
|
+
height: 63.034
|
|
14443
|
+
};
|
|
14444
|
+
const iconChevronRight = {
|
|
14445
|
+
path: "M62.808 49.728q0 3.36-2.352 5.88l-41.72 41.664q-2.352 2.408-5.768 2.408t-5.768-2.408l-4.872-4.76q-2.352-2.52-2.352-5.88t2.352-5.712l31.08-31.136-31.08-31.024q-2.352-2.52-2.352-5.88t2.352-5.712l4.872-4.76q2.296-2.408 5.768-2.408t5.768 2.408l41.72 41.664q2.352 2.296 2.352 5.656z",
|
|
14446
|
+
width: 63.034,
|
|
14447
|
+
height: 100
|
|
14448
|
+
};
|
|
14449
|
+
const iconCircle = {
|
|
14450
|
+
path: "M100.035 50.046q.057 13.623-6.669 25.137t-18.24 18.183-25.08 6.669-25.137-6.726q-11.514-6.726-18.183-18.183-6.726-11.571-6.726-25.137t6.726-25.08 18.24-18.24 25.08-6.669q13.566 0 25.08 6.726 11.514 6.669 18.24 18.183t6.669 25.137z",
|
|
14451
|
+
width: 100,
|
|
14452
|
+
height: 100
|
|
14453
|
+
};
|
|
14454
|
+
const iconCircleArrowDown = {
|
|
14455
|
+
path: "M50.046 83.676q1.767 0 2.907-1.14l29.526-29.526q1.197-1.197 1.197-2.907t-1.197-2.964l-5.928-5.928q-1.197-1.14-2.964-1.14t-2.907 1.14l-12.312 12.312l0-32.661q0-1.71-1.254-2.964t-2.907-1.254l-8.322 0q-1.71 0-2.964 1.254t-1.254 2.964l0 32.661l-12.312-12.312q-1.197-1.254-2.907-1.254t-2.907 1.254l-5.928 5.928q-1.197 1.197-1.197 2.964t1.197 2.907l29.469 29.526q1.197 1.14 2.964 1.14zm49.989-33.63q.057 13.623-6.669 25.137t-18.24 18.183-25.08 6.669-25.137-6.726q-11.514-6.726-18.183-18.183-6.726-11.571-6.726-25.137t6.726-25.08 18.24-18.24 25.08-6.669q13.566 0 25.08 6.726 11.514 6.669 18.24 18.183t6.669 25.137z",
|
|
14456
|
+
width: 100,
|
|
14457
|
+
height: 100
|
|
14458
|
+
};
|
|
14459
|
+
const iconCircleArrowUp = {
|
|
14460
|
+
path: "M54.207 83.391q1.653 0 2.907-1.254t1.254-2.907l0-32.718l12.312 12.312q1.254 1.254 2.964 1.254t2.907-1.254l5.928-5.928q1.197-1.197 1.14-2.964 0-1.767-1.14-2.907l-29.526-29.526q-1.197-1.14-2.907-1.14t-2.964 1.14l-29.469 29.526q-1.197 1.254-1.197 2.964t1.197 2.907l5.928 5.928q1.197 1.197 2.907 1.197t2.907-1.197l12.312-12.312l0 32.718q0 1.653 1.254 2.907t2.964 1.254l8.322 0zm45.828-33.345q.057 13.623-6.669 25.137t-18.24 18.183-25.08 6.669-25.137-6.726q-11.514-6.726-18.183-18.183-6.726-11.571-6.726-25.137t6.726-25.08 18.24-18.24 25.08-6.669q13.566 0 25.08 6.726 11.514 6.669 18.24 18.183t6.669 25.137z",
|
|
14461
|
+
width: 100,
|
|
14462
|
+
height: 100
|
|
14463
|
+
};
|
|
14464
|
+
const iconCircleThin = {
|
|
14465
|
+
path: "M50.046 8.322q-8.493 0-16.188 3.306-15.561 6.669-22.173 22.23-3.363 7.695-3.363 16.188t3.306 16.188 8.949 13.281q5.586 5.586 13.281 8.892t16.188 3.306 16.188-3.306 13.281-8.892 8.892-13.281 3.306-16.188-3.306-16.188-8.892-13.281-13.281-8.949q-7.695-3.306-16.188-3.306zm0 91.713q-13.623 0-25.137-6.726t-18.183-18.183q-6.726-11.571-6.726-25.137t6.726-25.08 18.24-18.24 25.08-6.669q13.566 0 25.08 6.726 11.514 6.669 18.24 18.183t6.726 25.137-6.726 25.137-18.24 18.126q-11.514 6.726-25.08 6.726z",
|
|
14466
|
+
width: 100,
|
|
14467
|
+
height: 99.944
|
|
14468
|
+
};
|
|
14469
|
+
const iconDesktop = {
|
|
14470
|
+
path: "M94.208 52.119l0-43.746q0-.69-.506-1.15t-1.196-.506l-84.088 0q-.69 0-1.196.506t-.506 1.15l0 43.746q0 .69.506 1.196t1.196.506l84.088 0q.69 0 1.196-.506t.506-1.196zm6.716-43.746l0 57.224q0 3.45-2.484 5.934t-5.934 2.484l-28.566 0q0 3.128 2.53 7.774.828 1.61.828 2.622t-1.012 2.07q-1.012 1.012-2.346.966l-26.91 0q-1.38 0-2.392-1.012t-1.012-2.024q0-1.058 1.656-4.14t1.748-6.256l-28.612 0q-3.45 0-5.934-2.484t-2.484-5.934l0-57.224q0-3.45 2.484-5.934t5.934-2.438l84.088 0q3.45 0 5.98 2.438 2.438 2.484 2.438 5.934z",
|
|
14471
|
+
width: 100,
|
|
14472
|
+
height: 86.648
|
|
14473
|
+
};
|
|
14474
|
+
const iconDropdownArrow = {
|
|
14475
|
+
path: "M9 9.8c0 .5.7 1.7 1.5 2.8 1.5 1.9 1.5 1.9 3 0C15.7 9.7 15.4 9 12 9c-1.6 0-3 .4-3 .8z",
|
|
14476
|
+
width: 24,
|
|
14477
|
+
height: 24
|
|
14478
|
+
};
|
|
14479
|
+
const iconExclamationSign = {
|
|
14480
|
+
path: "M58.368 81.225l0-12.369q0-.912-.57-1.539t-1.425-.627l-12.54 0q-.855-.057-1.482.627t-.684 1.539l0 12.369q-.057.855.627 1.482t1.539.684l12.54 0q.855 0 1.425-.627t.57-1.539zm1.026-62.871q0-1.596-2.223-1.71l-14.307 0q-2.109 0-2.223 1.71l1.14 40.47q0 .627.627 1.14t1.539.456l12.084 0q.912-.057 1.539-.513t.684-1.083zm-9.348-18.354q13.566 0 25.08 6.726 11.514 6.669 18.24 18.183t6.726 25.137-6.726 25.137-18.24 18.183-25.08 6.669-25.137-6.726q-11.514-6.726-18.183-18.183-6.726-11.571-6.726-25.137t6.726-25.08 18.24-18.24 25.08-6.669z",
|
|
14481
|
+
width: 100,
|
|
14482
|
+
height: 99.944
|
|
14483
|
+
};
|
|
14484
|
+
// Grabbed from https://github.com/encharm/Font-Awesome-SVG-PNG
|
|
14485
|
+
const iconGear = {
|
|
14486
|
+
path: "M1152 896q0-106-75-181t-181-75-181 75-75 181 75 181 181 75 181-75 75-181zm512-109v222q0 12-8 23t-20 13l-185 28q-19 54-39 91 35 50 107 138 10 12 10 25t-9 23q-27 37-99 108t-94 71q-12 0-26-9l-138-108q-44 23-91 38-16 136-29 186-7 28-36 28h-222q-14 0-24.5-8.5t-11.5-21.5l-28-184q-49-16-90-37l-141 107q-10 9-25 9-14 0-25-11-126-114-165-168-7-10-7-23 0-12 8-23 15-21 51-66.5t54-70.5q-27-50-41-99l-183-27q-13-2-21-12.5t-8-23.5v-222q0-12 8-23t19-13l186-28q14-46 39-92-40-57-107-138-10-12-10-24 0-10 9-23 26-36 98.5-107.5t94.5-71.5q13 0 26 10l138 107q44-23 91-38 16-136 29-186 7-28 36-28h222q14 0 24.5 8.5t11.5 21.5l28 184q49 16 90 37l142-107q9-9 24-9 13 0 25 10 129 119 165 170 7 8 7 22 0 12-8 23-15 21-51 66.5t-54 70.5q26 50 41 98l183 28q13 2 21 12.5t8 23.5z",
|
|
14487
|
+
width: 1792,
|
|
14488
|
+
height: 1792
|
|
14489
|
+
};
|
|
14490
|
+
const iconMobilePhone = {
|
|
14491
|
+
path: "M36.04 89.557q0-2.584-1.836-4.42t-4.42-1.836-4.352 1.836q-1.836 1.836-1.836 4.42t1.836 4.352 4.42 1.836q2.652-.068 4.42-1.836t1.768-4.352zm16.184-12.444l0-54.74q0-1.088-.748-1.768t-1.768-.68l-39.78 0q-1.088 0-1.768.748t-.68 1.7l0 54.74q0 1.02.748 1.768t1.7.68l39.78 0q1.02-.068 1.768-.748t.748-1.7zm-14.892-65.892q0-1.224-1.292-1.292l-12.444 0q-1.224.068-1.224 1.292t1.224 1.224l12.444 0q1.292 0 1.292-1.224zm22.372-1.292l0 79.628q0 3.944-2.992 6.936t-7.004 2.992l-39.78 0q-4.012 0-7.004-2.924-2.924-2.924-2.924-7.004l0-79.628q0-4.012 2.924-6.936t7.004-2.992l39.78 0q4.012-.068 7.004 2.924t2.992 7.004z",
|
|
14492
|
+
width: 60.013,
|
|
14493
|
+
height: 100
|
|
14494
|
+
};
|
|
14495
|
+
const iconOk = {
|
|
14496
|
+
path: "M37.964 76.048q-2.576 0-4.368-1.792l-31.864-31.864q-1.792-1.792-1.792-4.368t1.792-4.368l8.736-8.68q1.792-1.792 4.368-1.792t4.312 1.792l18.816 18.872 42-42.056q1.792-1.792 4.368-1.792t4.312 1.792l8.736 8.736q1.792 1.792 1.792 4.368t-1.792 4.312l-55.048 55.048q-1.792 1.792-4.368 1.792z",
|
|
14497
|
+
width: 100,
|
|
14498
|
+
height: 76.637
|
|
14499
|
+
};
|
|
14500
|
+
const iconPlus = {
|
|
14501
|
+
path: "M99.758 43.09l0 13.578q0 2.852-1.984 4.836t-4.836 1.984l-29.45 0l0 29.45q0 2.852-1.984 4.836t-4.836 1.984l-13.578 0q-2.852 0-4.836-1.984t-1.984-4.836l0-29.45l-29.45 0q-2.852 0-4.836-1.984t-1.984-4.836l0-13.578q0-2.852 1.984-4.836t4.836-1.984l29.45 0l0-29.45q0-2.852 1.984-4.836t4.836-1.984l13.578 0q2.852 0 4.836 1.984t1.984 4.836l0 29.45l29.45 0q2.852 0 4.836 1.984t1.984 4.836z",
|
|
14502
|
+
width: 100,
|
|
14503
|
+
height: 100
|
|
14504
|
+
};
|
|
14505
|
+
const iconRemove = {
|
|
14506
|
+
path: "M100.464 80.808q0 3.404-2.368 5.772l-11.47 11.544q-2.368 2.368-5.772 2.368t-5.698-2.368l-24.864-24.864-24.864 24.864q-2.368 2.368-5.772 2.368t-5.772-2.368l-11.47-11.544q-2.368-2.368-2.368-5.772t2.368-5.698l24.864-24.864-24.864-24.864q-2.368-2.368-2.368-5.772t2.368-5.772l11.47-11.47q2.368-2.368 5.772-2.368t5.772 2.368l24.864 24.864 24.864-24.864q2.294-2.368 5.698-2.368t5.772 2.368l11.47 11.47q2.368 2.368 2.368 5.772t-2.368 5.772l-24.864 24.864 24.864 24.864q2.368 2.294 2.368 5.698z",
|
|
14507
|
+
width: 100,
|
|
14508
|
+
height: 100
|
|
14509
|
+
};
|
|
14510
|
+
const iconStar = {
|
|
14511
|
+
path: "M15.1052249,9.55978547 L22.0028147,9.55978545 C23.6568673,9.55978545 23.9349557,10.3753626 22.6181351,11.3858845 L16.9943688,15.7015366 L19.2518801,22.8294455 C19.7526645,24.4106317 19.0984455,24.8825885 17.769353,23.8673293 L12.0490577,19.4977438 L6.5116497,23.8422153 C5.20921411,24.8640642 4.53299569,24.4067544 5.00266927,22.8160582 L7.10332364,15.7015366 L1.42794544,11.3634306 C0.110226041,10.3562014 0.383967283,9.54239221 2.0409646,9.54574013 L8.9924676,9.55978547 L11.1485117,2.72669438 C11.6458693,1.15043244 12.4548928,1.15900049 12.9494787,2.72669438 L15.1052249,9.55978547 Z",
|
|
14512
|
+
width: 24,
|
|
14513
|
+
height: 24
|
|
14514
|
+
};
|
|
14515
|
+
const iconTryAgain = {
|
|
14516
|
+
path: "M3.74890556,17.9799506 C2.19251241,16.1970909 1.10103636,13.4971457 1.13090903,11.1491783 C1.17160478,7.95052637 4.01704076,0.865059407 11.7028044,0.865059407 C19.388568,0.865059407 22.3026521,7.35203035 22.3026521,11.5879453 C22.3026521,15.8238603 19.386629,20.5574509 13.6832464,21.7131548 L13.6757539,17.3722171 C17.0812986,16.2190517 18.331158,14.1944123 18.3311578,11.5879451 C18.3311574,8.16554692 15.6664205,5.03476549 11.7028048,5.20494205 C7.73918903,5.37511861 5.59244567,8.66930079 5.59244567,11.1491783 C5.59244567,12.9090077 6.11128139,14.1753512 6.93640437,15.3053215 L8.14052356,14.2949456 C8.98559348,13.5858477 9.6994861,13.9070448 9.73489556,15.0076413 L9.91284941,20.5388014 C9.94832683,21.6415103 9.09967118,22.3514475 8.02194403,22.1254594 L2.60571602,20.9897332 C1.5259204,20.7633114 1.34338662,19.9984207 2.18070755,19.295825 L3.74890556,17.9799506 Z",
|
|
14517
|
+
width: 23,
|
|
14518
|
+
height: 23
|
|
14519
|
+
};
|
|
14520
|
+
const iconTablet = {
|
|
14521
|
+
path: "M45.322 90.706q0-1.86-1.302-3.224-1.364-1.364-3.224-1.364t-3.224 1.364-1.302 3.224q0 1.86 1.364 3.224 1.302 1.364 3.162 1.302 1.86.062 3.224-1.302t1.302-3.224zm27.218-11.346l0-68.014q0-.93-.682-1.612t-1.55-.682l-58.962 0q-.93 0-1.612.682t-.682 1.612l0 68.014q0 .93.682 1.612t1.612.62l58.962 0q.992-.062 1.612-.682t.62-1.55zm9.114-68.014l0 77.066q0 4.65-3.348 7.998t-7.998 3.348l-58.962 0q-4.65 0-7.998-3.348t-3.348-7.998l0-77.066q0-4.65 3.348-7.998t7.998-3.348l58.962 0q4.65 0 7.998 3.348t3.348 7.998z",
|
|
14522
|
+
width: 81.852,
|
|
14523
|
+
height: 100
|
|
14524
|
+
};
|
|
14525
|
+
const iconTrash = {
|
|
14526
|
+
path: "M31.293 37.506q2.052 0 2.052 2.109l0 37.506q0 1.995-2.052 2.109l-4.218 0q-.912-.057-1.482-.627t-.57-1.482l0-37.506q0-2.109 2.052-2.109l4.218 0zm18.753 2.109l0 37.506q0 .912-.57 1.482t-1.539.627l-4.161 0q-1.995 0-2.109-2.109l0-37.506q.057-.912.627-1.482t1.482-.627l4.161 0q.969.057 1.539.627t.57 1.482zm14.592-2.109q2.052 0 2.052 2.109l0 37.506q0 1.995-2.052 2.109l-4.161 0q-.969-.057-1.539-.627t-.57-1.482l0-37.506q0-2.109 2.109-2.109l4.161 0zm10.431 49.248l0-61.731l-58.368 0l0 61.731q.057 2.679.969 3.819t1.083 1.14l54.207 0q.171 0 1.14-1.083t.969-3.876zm-43.776-70.11l29.184 0l-3.135-7.581q-.456-.57-1.14-.741l-20.634 0q-.627.114-1.083.741zm-31.293 2.109q0-1.995 2.109-2.109l20.121 0l4.56-10.83q.969-2.394 3.477-4.104 2.565-1.71 5.187-1.71l20.805 0q2.622 0 5.187 1.71t3.477 4.104l4.56 10.83l20.178 0q.912.057 1.482.627t.57 1.482l0 4.161q0 1.995-2.052 2.109l-6.27 0l0 61.731q0 5.415-3.078 9.348t-7.353 3.933l-54.207 0q-4.275 0-7.353-3.819t-3.078-9.177l0-62.016l-6.213 0q-.969 0-1.539-.57t-.57-1.539l0-4.161z",
|
|
14527
|
+
width: 91.681,
|
|
14528
|
+
height: 100
|
|
14529
|
+
};
|
|
14530
|
+
const iconUndo = {
|
|
14531
|
+
path: "M10,6.6C10,7.2,9.8,8,9.3,9.1c0,0,0,0.1-0.1,0.1S9.2,9.3,9.2,9.4c0,0,0,0.1-0.1,0.1C9,9.6,9,9.6,8.9,9.6 c-0.1,0-0.1,0-0.1-0.1c0,0,0-0.1,0-0.1c0,0,0-0.1,0-0.1s0-0.1,0-0.1c0-0.3,0-0.5,0-0.7c0-0.4,0-0.7-0.1-1C8.6,7.1,8.5,6.9,8.4,6.7S8.2,6.3,8,6.1C7.8,5.9,7.6,5.8,7.4,5.7S6.9,5.5,6.7,5.5S6.1,5.4,5.8,5.4c-0.3,0-0.6,0-1,0H3.6v1.4c0,0.1,0,0.2-0.1,0.3C3.4,7.1,3.3,7.1,3.2,7.1C3.1,7.1,3,7.1,3,7L0.1,4.1C0,4.1,0,4,0,3.9s0-0.2,0.1-0.3L3,0.8C3,0.7,3.1,0.7,3.2,0.7c0.1,0,0.2,0,0.3,0.1C3.5,0.9,3.6,0.9,3.6,1v1.4h1.2c2.6,0,4.3,0.7,4.9,2.2C9.9,5.2,10,5.8,10,6.6z",
|
|
14532
|
+
width: 10,
|
|
14533
|
+
height: 10
|
|
14534
|
+
};
|
|
14535
|
+
const iconMinus = {
|
|
14536
|
+
path: `M8,13 L16,13 C16.5522847,13 17,12.5522847 17,12 C17,11.4477153 16.5522847,11 16,11 L8,11 C7.44771525,11 7,11.4477153 7,12 C7,12.5522847 7.44771525,13 8,13 Z`,
|
|
14537
|
+
width: 24,
|
|
14538
|
+
height: 24
|
|
14539
|
+
};
|
|
14540
|
+
|
|
14541
|
+
var iconPaths = /*#__PURE__*/Object.freeze({
|
|
14542
|
+
__proto__: null,
|
|
14543
|
+
iconCheck: iconCheck,
|
|
14544
|
+
iconCheckMedium: iconCheckMedium,
|
|
14545
|
+
iconChevronDown: iconChevronDown,
|
|
14546
|
+
iconChevronRight: iconChevronRight,
|
|
14547
|
+
iconCircle: iconCircle,
|
|
14548
|
+
iconCircleArrowDown: iconCircleArrowDown,
|
|
14549
|
+
iconCircleArrowUp: iconCircleArrowUp,
|
|
14550
|
+
iconCircleThin: iconCircleThin,
|
|
14551
|
+
iconDesktop: iconDesktop,
|
|
14552
|
+
iconDropdownArrow: iconDropdownArrow,
|
|
14553
|
+
iconExclamationSign: iconExclamationSign,
|
|
14554
|
+
iconGear: iconGear,
|
|
14555
|
+
iconMobilePhone: iconMobilePhone,
|
|
14556
|
+
iconOk: iconOk,
|
|
14557
|
+
iconPlus: iconPlus,
|
|
14558
|
+
iconRemove: iconRemove,
|
|
14559
|
+
iconStar: iconStar,
|
|
14560
|
+
iconTryAgain: iconTryAgain,
|
|
14561
|
+
iconTablet: iconTablet,
|
|
14562
|
+
iconTrash: iconTrash,
|
|
14563
|
+
iconUndo: iconUndo,
|
|
14564
|
+
iconMinus: iconMinus
|
|
14565
|
+
});
|
|
14566
|
+
|
|
14952
14567
|
/* eslint-disable @babel/no-invalid-this */
|
|
14953
14568
|
const add$1 = {
|
|
14954
14569
|
constrain: function () {
|
|
@@ -20819,6 +20434,258 @@ TextInput.defaultProps = {
|
|
|
20819
20434
|
disabled: false
|
|
20820
20435
|
};
|
|
20821
20436
|
|
|
20437
|
+
/* eslint-disable react/no-unsafe */
|
|
20438
|
+
const zIndex = 10;
|
|
20439
|
+
let HorizontalDirection = /*#__PURE__*/function (HorizontalDirection) {
|
|
20440
|
+
HorizontalDirection["Left"] = "left";
|
|
20441
|
+
HorizontalDirection["Right"] = "right";
|
|
20442
|
+
return HorizontalDirection;
|
|
20443
|
+
}({});
|
|
20444
|
+
let VerticalDirection = /*#__PURE__*/function (VerticalDirection) {
|
|
20445
|
+
VerticalDirection["Top"] = "top";
|
|
20446
|
+
VerticalDirection["Bottom"] = "bottom";
|
|
20447
|
+
return VerticalDirection;
|
|
20448
|
+
}({});
|
|
20449
|
+
const Triangle = props => {
|
|
20450
|
+
let borderLeft;
|
|
20451
|
+
let borderRight;
|
|
20452
|
+
let borderTop;
|
|
20453
|
+
let borderBottom;
|
|
20454
|
+
const hBorder = `${props.width}px solid transparent`;
|
|
20455
|
+
if (props.horizontalDirection === "right") {
|
|
20456
|
+
borderLeft = hBorder;
|
|
20457
|
+
} else {
|
|
20458
|
+
borderRight = hBorder;
|
|
20459
|
+
}
|
|
20460
|
+
const vBorder = `${props.height}px solid ${props.color}`;
|
|
20461
|
+
if (props.verticalDirection === "top") {
|
|
20462
|
+
borderTop = vBorder;
|
|
20463
|
+
} else {
|
|
20464
|
+
borderBottom = vBorder;
|
|
20465
|
+
}
|
|
20466
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
20467
|
+
style: {
|
|
20468
|
+
display: "block",
|
|
20469
|
+
height: 0,
|
|
20470
|
+
width: 0,
|
|
20471
|
+
position: "absolute",
|
|
20472
|
+
left: props.left,
|
|
20473
|
+
top: props["top"],
|
|
20474
|
+
borderLeft: borderLeft,
|
|
20475
|
+
borderRight: borderRight,
|
|
20476
|
+
borderTop: borderTop,
|
|
20477
|
+
borderBottom: borderBottom
|
|
20478
|
+
}
|
|
20479
|
+
});
|
|
20480
|
+
};
|
|
20481
|
+
const TooltipArrow = props => {
|
|
20482
|
+
// TODO(aria): Think about adding a box-shadow to the triangle here
|
|
20483
|
+
// See http://css-tricks.com/triangle-with-shadow/
|
|
20484
|
+
|
|
20485
|
+
//const isRight = (this.props.horizontalDirection === "right");
|
|
20486
|
+
const isTop = props.verticalDirection === "top";
|
|
20487
|
+
const frontTopOffset = isTop ? 0 : 1;
|
|
20488
|
+
const borderTopOffset = isTop ? 0 : -1;
|
|
20489
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
20490
|
+
style: {
|
|
20491
|
+
display: "block",
|
|
20492
|
+
position: props.position,
|
|
20493
|
+
visibility: props.visibility,
|
|
20494
|
+
left: props.left,
|
|
20495
|
+
top: props["top"],
|
|
20496
|
+
width: props.width + 2,
|
|
20497
|
+
height: props.height + 1,
|
|
20498
|
+
marginTop: -1,
|
|
20499
|
+
marginBottom: -2,
|
|
20500
|
+
zIndex: zIndex
|
|
20501
|
+
}
|
|
20502
|
+
}, /*#__PURE__*/React.createElement(Triangle, {
|
|
20503
|
+
horizontalDirection: props.horizontalDirection,
|
|
20504
|
+
verticalDirection: props.verticalDirection,
|
|
20505
|
+
color: props.border,
|
|
20506
|
+
left: 0,
|
|
20507
|
+
top: borderTopOffset,
|
|
20508
|
+
width: props.width + 2 // one extra for the diagonal
|
|
20509
|
+
,
|
|
20510
|
+
height: props.height + 2
|
|
20511
|
+
}), /*#__PURE__*/React.createElement(Triangle, {
|
|
20512
|
+
horizontalDirection: props.horizontalDirection,
|
|
20513
|
+
verticalDirection: props.verticalDirection,
|
|
20514
|
+
color: props.color,
|
|
20515
|
+
left: 1,
|
|
20516
|
+
top: frontTopOffset,
|
|
20517
|
+
width: props.width,
|
|
20518
|
+
height: props.height
|
|
20519
|
+
}));
|
|
20520
|
+
};
|
|
20521
|
+
TooltipArrow.defaultProps = {
|
|
20522
|
+
position: "relative",
|
|
20523
|
+
visibility: "visible",
|
|
20524
|
+
left: 0,
|
|
20525
|
+
top: 0
|
|
20526
|
+
};
|
|
20527
|
+
const VERTICAL_CORNERS = {
|
|
20528
|
+
top: {
|
|
20529
|
+
top: "-100%"
|
|
20530
|
+
},
|
|
20531
|
+
bottom: {
|
|
20532
|
+
top: 0
|
|
20533
|
+
}
|
|
20534
|
+
};
|
|
20535
|
+
const HORIZONTAL_CORNERS = {
|
|
20536
|
+
left: {
|
|
20537
|
+
targetLeft: 0
|
|
20538
|
+
},
|
|
20539
|
+
right: {
|
|
20540
|
+
targetLeft: "100%"
|
|
20541
|
+
}
|
|
20542
|
+
};
|
|
20543
|
+
const HORIZONTAL_ALIGNMNENTS = {
|
|
20544
|
+
left: {
|
|
20545
|
+
tooltipLeft: 0,
|
|
20546
|
+
arrowLeft: arrowSize => 0
|
|
20547
|
+
},
|
|
20548
|
+
right: {
|
|
20549
|
+
tooltipLeft: "-100%",
|
|
20550
|
+
arrowLeft: arrowSize => -arrowSize - 2
|
|
20551
|
+
}
|
|
20552
|
+
};
|
|
20553
|
+
class Tooltip extends React.Component {
|
|
20554
|
+
constructor(...args) {
|
|
20555
|
+
super(...args);
|
|
20556
|
+
this.state = {
|
|
20557
|
+
height: null // used for offsetting "top" positioned tooltips
|
|
20558
|
+
};
|
|
20559
|
+
}
|
|
20560
|
+
|
|
20561
|
+
componentDidMount() {
|
|
20562
|
+
this._updateHeight();
|
|
20563
|
+
}
|
|
20564
|
+
UNSAFE_componentWillReceiveProps() {
|
|
20565
|
+
// If the contents have changed, reset our measure of the height
|
|
20566
|
+
this.setState({
|
|
20567
|
+
height: null
|
|
20568
|
+
});
|
|
20569
|
+
}
|
|
20570
|
+
componentDidUpdate() {
|
|
20571
|
+
this._updateHeight();
|
|
20572
|
+
}
|
|
20573
|
+
_renderToolTipDiv(isTooltipAbove) {
|
|
20574
|
+
const settings = Object.assign({}, HORIZONTAL_CORNERS[this.props.horizontalPosition], HORIZONTAL_ALIGNMNENTS[this.props.horizontalAlign], VERTICAL_CORNERS[this.props.verticalPosition]);
|
|
20575
|
+
let arrowAbove;
|
|
20576
|
+
let arrowBelow;
|
|
20577
|
+
if (isTooltipAbove) {
|
|
20578
|
+
// We put an absolutely positioned arrow in the correct place
|
|
20579
|
+
arrowAbove = /*#__PURE__*/React.createElement(TooltipArrow, {
|
|
20580
|
+
verticalDirection: VerticalDirection.Top,
|
|
20581
|
+
horizontalDirection: this.props.horizontalAlign,
|
|
20582
|
+
position: "absolute",
|
|
20583
|
+
color: "white",
|
|
20584
|
+
border: this.props.borderColor,
|
|
20585
|
+
left: settings.arrowLeft(this.props.arrowSize),
|
|
20586
|
+
top: -this.props.arrowSize + 2,
|
|
20587
|
+
width: this.props.arrowSize,
|
|
20588
|
+
height: this.props.arrowSize,
|
|
20589
|
+
zIndex: zIndex
|
|
20590
|
+
});
|
|
20591
|
+
|
|
20592
|
+
// And we use a visibility: hidden arrow below to shift up the
|
|
20593
|
+
// content by the correct amount
|
|
20594
|
+
arrowBelow = /*#__PURE__*/React.createElement(TooltipArrow, {
|
|
20595
|
+
verticalDirection: VerticalDirection.Top,
|
|
20596
|
+
horizontalDirection: this.props.horizontalAlign,
|
|
20597
|
+
visibility: "hidden",
|
|
20598
|
+
color: "white",
|
|
20599
|
+
border: this.props.borderColor,
|
|
20600
|
+
left: settings.arrowLeft(this.props.arrowSize),
|
|
20601
|
+
top: -1,
|
|
20602
|
+
width: this.props.arrowSize,
|
|
20603
|
+
height: this.props.arrowSize,
|
|
20604
|
+
zIndex: zIndex
|
|
20605
|
+
});
|
|
20606
|
+
} else {
|
|
20607
|
+
arrowAbove = /*#__PURE__*/React.createElement(TooltipArrow, {
|
|
20608
|
+
verticalDirection: VerticalDirection.Bottom,
|
|
20609
|
+
horizontalDirection: this.props.horizontalAlign,
|
|
20610
|
+
color: "white",
|
|
20611
|
+
border: this.props.borderColor,
|
|
20612
|
+
left: settings.arrowLeft(this.props.arrowSize),
|
|
20613
|
+
top: -1,
|
|
20614
|
+
width: this.props.arrowSize,
|
|
20615
|
+
height: this.props.arrowSize,
|
|
20616
|
+
zIndex: zIndex
|
|
20617
|
+
});
|
|
20618
|
+
arrowBelow = null;
|
|
20619
|
+
}
|
|
20620
|
+
|
|
20621
|
+
/* A positioned div below the input to be the parent for our
|
|
20622
|
+
tooltip */
|
|
20623
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
20624
|
+
style: {
|
|
20625
|
+
position: "relative",
|
|
20626
|
+
height: 0,
|
|
20627
|
+
display: this.props.show ? "block" : "none"
|
|
20628
|
+
}
|
|
20629
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
20630
|
+
// eslint-disable-next-line react/no-string-refs
|
|
20631
|
+
ref: "tooltipContainer",
|
|
20632
|
+
className: "tooltipContainer",
|
|
20633
|
+
style: {
|
|
20634
|
+
position: "absolute",
|
|
20635
|
+
// height must start out undefined, not null, so that
|
|
20636
|
+
// we can measure the actual height with jquery.
|
|
20637
|
+
// This is used to position the tooltip with top: -100%
|
|
20638
|
+
// when in verticalPosition: "top" mode
|
|
20639
|
+
height: this.state.height || undefined,
|
|
20640
|
+
left: settings.targetLeft
|
|
20641
|
+
}
|
|
20642
|
+
}, arrowAbove, /*#__PURE__*/React.createElement("div", {
|
|
20643
|
+
className: this.props.className
|
|
20644
|
+
// eslint-disable-next-line react/no-string-refs
|
|
20645
|
+
,
|
|
20646
|
+
ref: "tooltipContent",
|
|
20647
|
+
style: {
|
|
20648
|
+
position: "relative",
|
|
20649
|
+
top: settings["top"],
|
|
20650
|
+
left: settings.tooltipLeft,
|
|
20651
|
+
border: "1px solid " + this.props.borderColor,
|
|
20652
|
+
boxShadow: "0 1px 3px " + this.props.borderColor,
|
|
20653
|
+
zIndex: zIndex - 1
|
|
20654
|
+
}
|
|
20655
|
+
}, this.props.children.slice(1)), arrowBelow));
|
|
20656
|
+
}
|
|
20657
|
+
_updateHeight() {
|
|
20658
|
+
const tooltipContainer = ReactDOM__default.findDOMNode(
|
|
20659
|
+
// eslint-disable-next-line react/no-string-refs
|
|
20660
|
+
this.refs.tooltipContainer);
|
|
20661
|
+
const height = tooltipContainer.offsetHeight;
|
|
20662
|
+
if (height !== this.state.height) {
|
|
20663
|
+
this.setState({
|
|
20664
|
+
height
|
|
20665
|
+
});
|
|
20666
|
+
}
|
|
20667
|
+
}
|
|
20668
|
+
render() {
|
|
20669
|
+
const isTooltipAbove = this.props.verticalPosition === "top";
|
|
20670
|
+
|
|
20671
|
+
/* We wrap the entire output in a span so that it displays inline */
|
|
20672
|
+
return /*#__PURE__*/React.createElement("span", null, isTooltipAbove && this._renderToolTipDiv(isTooltipAbove), /*#__PURE__*/React.createElement("div", {
|
|
20673
|
+
style: this.props.targetContainerStyle
|
|
20674
|
+
}, this.props.children[0]), !isTooltipAbove && this._renderToolTipDiv());
|
|
20675
|
+
}
|
|
20676
|
+
}
|
|
20677
|
+
|
|
20678
|
+
// Sorry. // Apology-Oriented-Programming
|
|
20679
|
+
Tooltip.defaultProps = {
|
|
20680
|
+
className: "",
|
|
20681
|
+
arrowSize: 10,
|
|
20682
|
+
borderColor: "#ccc",
|
|
20683
|
+
verticalPosition: VerticalDirection.Bottom,
|
|
20684
|
+
horizontalPosition: HorizontalDirection.Left,
|
|
20685
|
+
horizontalAlign: HorizontalDirection.Left,
|
|
20686
|
+
targetContainerStyle: {}
|
|
20687
|
+
};
|
|
20688
|
+
|
|
20822
20689
|
/* eslint-disable react/sort-comp */
|
|
20823
20690
|
const {
|
|
20824
20691
|
captureScratchpadTouchStart: captureScratchpadTouchStart$3
|
|
@@ -24608,26 +24475,6 @@ var Explanation$1 = {
|
|
|
24608
24475
|
isLintable: true
|
|
24609
24476
|
};
|
|
24610
24477
|
|
|
24611
|
-
/*
|
|
24612
|
-
* A11y (Accessibility) style rules
|
|
24613
|
-
* These are used to mark up areas on the site that should only be readable
|
|
24614
|
-
* when using a screen reader.
|
|
24615
|
-
*/
|
|
24616
|
-
var a11y = StyleSheet.create({
|
|
24617
|
-
// Make content only visible to screen readers.
|
|
24618
|
-
// Both collegeboard.org and Bootstrap 3 use this exact implementation.
|
|
24619
|
-
srOnly: {
|
|
24620
|
-
border: 0,
|
|
24621
|
-
clip: "rect(0,0,0,0)",
|
|
24622
|
-
height: 1,
|
|
24623
|
-
margin: -1,
|
|
24624
|
-
overflow: "hidden",
|
|
24625
|
-
padding: 0,
|
|
24626
|
-
position: "absolute",
|
|
24627
|
-
width: 1
|
|
24628
|
-
}
|
|
24629
|
-
});
|
|
24630
|
-
|
|
24631
24478
|
class GradedGroupAnswerBar extends React.Component {
|
|
24632
24479
|
render() {
|
|
24633
24480
|
const {
|
|
@@ -43895,7 +43742,7 @@ const init = function init(options) {
|
|
|
43895
43742
|
|
|
43896
43743
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
43897
43744
|
const libName = "@khanacademy/perseus";
|
|
43898
|
-
const libVersion = "
|
|
43745
|
+
const libVersion = "12.0.0";
|
|
43899
43746
|
addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
43900
43747
|
|
|
43901
43748
|
const apiVersion = {
|
|
@@ -45611,6 +45458,239 @@ RangeInput.defaultProps = {
|
|
|
45611
45458
|
placeholder: [null, null]
|
|
45612
45459
|
};
|
|
45613
45460
|
|
|
45461
|
+
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
45462
|
+
const prettyBig = {
|
|
45463
|
+
fontSize: "150%"
|
|
45464
|
+
};
|
|
45465
|
+
const slightlyBig = {
|
|
45466
|
+
fontSize: "120%"
|
|
45467
|
+
};
|
|
45468
|
+
const symbStyle = {
|
|
45469
|
+
fontSize: "130%"
|
|
45470
|
+
};
|
|
45471
|
+
// These are functions because we want to generate a new component for each use
|
|
45472
|
+
// on the page rather than reusing an instance (which will cause an error).
|
|
45473
|
+
// Also, it's useful for things which might look different depending on the
|
|
45474
|
+
// props.
|
|
45475
|
+
|
|
45476
|
+
const basic = [() => [/*#__PURE__*/React.createElement("span", {
|
|
45477
|
+
key: "plus",
|
|
45478
|
+
style: slightlyBig
|
|
45479
|
+
}, "+"), "PLUS", i18n._("Plus")], () => [/*#__PURE__*/React.createElement("span", {
|
|
45480
|
+
key: "minus",
|
|
45481
|
+
style: prettyBig
|
|
45482
|
+
}, "-"), "MINUS", i18n._("Minus")],
|
|
45483
|
+
// TODO(joel) - display as \cdot when appropriate
|
|
45484
|
+
props => {
|
|
45485
|
+
const {
|
|
45486
|
+
TeX
|
|
45487
|
+
} = getDependencies();
|
|
45488
|
+
if (props.convertDotToTimes) {
|
|
45489
|
+
return [/*#__PURE__*/React.createElement(TeX, {
|
|
45490
|
+
key: "times",
|
|
45491
|
+
style: prettyBig
|
|
45492
|
+
}, i18n.doNotTranslate("\\times")), "TIMES", i18n._("Multiply")];
|
|
45493
|
+
}
|
|
45494
|
+
return [/*#__PURE__*/React.createElement(TeX, {
|
|
45495
|
+
key: "times",
|
|
45496
|
+
style: prettyBig
|
|
45497
|
+
}, i18n.doNotTranslate("\\cdot")), "CDOT", i18n._("Multiply")];
|
|
45498
|
+
}, () => {
|
|
45499
|
+
const {
|
|
45500
|
+
TeX
|
|
45501
|
+
} = getDependencies();
|
|
45502
|
+
return [/*#__PURE__*/React.createElement(TeX, {
|
|
45503
|
+
key: "frac",
|
|
45504
|
+
style: prettyBig
|
|
45505
|
+
}, i18n.doNotTranslate("\\frac{x}{y}")), "FRAC", i18n._("Fraction, excluding the current expression")];
|
|
45506
|
+
}];
|
|
45507
|
+
const buttonSets = {
|
|
45508
|
+
basic,
|
|
45509
|
+
"basic+div": basic.concat([() => {
|
|
45510
|
+
const {
|
|
45511
|
+
TeX
|
|
45512
|
+
} = getDependencies();
|
|
45513
|
+
return [/*#__PURE__*/React.createElement(TeX, {
|
|
45514
|
+
key: "div"
|
|
45515
|
+
}, i18n.doNotTranslate("\\div")), "DIVIDE", i18n._("Divide")];
|
|
45516
|
+
}]),
|
|
45517
|
+
trig: [() => {
|
|
45518
|
+
const {
|
|
45519
|
+
TeX
|
|
45520
|
+
} = getDependencies();
|
|
45521
|
+
return [/*#__PURE__*/React.createElement(TeX, {
|
|
45522
|
+
key: "sin"
|
|
45523
|
+
}, i18n.doNotTranslate("\\sin")), "SIN", i18n._("Sine")];
|
|
45524
|
+
}, () => {
|
|
45525
|
+
const {
|
|
45526
|
+
TeX
|
|
45527
|
+
} = getDependencies();
|
|
45528
|
+
return [/*#__PURE__*/React.createElement(TeX, {
|
|
45529
|
+
key: "cos"
|
|
45530
|
+
}, i18n.doNotTranslate("\\cos")), "COS", i18n._("Cosine")];
|
|
45531
|
+
}, () => {
|
|
45532
|
+
const {
|
|
45533
|
+
TeX
|
|
45534
|
+
} = getDependencies();
|
|
45535
|
+
return [/*#__PURE__*/React.createElement(TeX, {
|
|
45536
|
+
key: "tan"
|
|
45537
|
+
}, i18n.doNotTranslate("\\tan")), "TAN", i18n._("Tangent")];
|
|
45538
|
+
}, () => {
|
|
45539
|
+
const {
|
|
45540
|
+
TeX
|
|
45541
|
+
} = getDependencies();
|
|
45542
|
+
return [/*#__PURE__*/React.createElement(TeX, {
|
|
45543
|
+
key: "theta",
|
|
45544
|
+
style: symbStyle
|
|
45545
|
+
}, i18n.doNotTranslate("\\theta")), "THETA", i18n._("Theta")];
|
|
45546
|
+
}, () => {
|
|
45547
|
+
const {
|
|
45548
|
+
TeX
|
|
45549
|
+
} = getDependencies();
|
|
45550
|
+
return [/*#__PURE__*/React.createElement("span", {
|
|
45551
|
+
key: "phi"
|
|
45552
|
+
}, /*#__PURE__*/React.createElement("span", {
|
|
45553
|
+
className: "perseus-sr-only"
|
|
45554
|
+
}, i18n.doNotTranslate("phi")), /*#__PURE__*/React.createElement(TeX, {
|
|
45555
|
+
key: "pi",
|
|
45556
|
+
style: symbStyle
|
|
45557
|
+
}, i18n.doNotTranslate("\\phi"))), "PHI", i18n._("Phi")];
|
|
45558
|
+
}],
|
|
45559
|
+
prealgebra: [() => {
|
|
45560
|
+
const {
|
|
45561
|
+
TeX
|
|
45562
|
+
} = getDependencies();
|
|
45563
|
+
return [/*#__PURE__*/React.createElement(TeX, {
|
|
45564
|
+
key: "sqrt"
|
|
45565
|
+
}, i18n.doNotTranslate("\\sqrt{x}")), "SQRT", i18n._("Square root")];
|
|
45566
|
+
},
|
|
45567
|
+
// TODO(joel) - how does desmos do this?
|
|
45568
|
+
() => {
|
|
45569
|
+
const {
|
|
45570
|
+
TeX
|
|
45571
|
+
} = getDependencies();
|
|
45572
|
+
return [/*#__PURE__*/React.createElement(TeX, {
|
|
45573
|
+
key: "nthroot"
|
|
45574
|
+
}, i18n.doNotTranslate("\\sqrt[3]{x}")), "NTHROOT3", i18n._("Cube root")];
|
|
45575
|
+
}, () => {
|
|
45576
|
+
const {
|
|
45577
|
+
TeX
|
|
45578
|
+
} = getDependencies();
|
|
45579
|
+
return [/*#__PURE__*/React.createElement(TeX, {
|
|
45580
|
+
key: "pow",
|
|
45581
|
+
style: slightlyBig
|
|
45582
|
+
}, i18n.doNotTranslate("a^b")), "POW", i18n._("Exponent")];
|
|
45583
|
+
}, () => {
|
|
45584
|
+
const {
|
|
45585
|
+
TeX
|
|
45586
|
+
} = getDependencies();
|
|
45587
|
+
return [/*#__PURE__*/React.createElement(TeX, {
|
|
45588
|
+
key: "pi",
|
|
45589
|
+
style: slightlyBig
|
|
45590
|
+
}, i18n.doNotTranslate("\\pi")), "PI", i18n._("Pi")];
|
|
45591
|
+
}],
|
|
45592
|
+
logarithms: [() => {
|
|
45593
|
+
const {
|
|
45594
|
+
TeX
|
|
45595
|
+
} = getDependencies();
|
|
45596
|
+
return [/*#__PURE__*/React.createElement(TeX, {
|
|
45597
|
+
key: "log"
|
|
45598
|
+
}, i18n.doNotTranslate("\\log")), "LOG", i18n._("Logarithm with base 10")];
|
|
45599
|
+
}, () => {
|
|
45600
|
+
const {
|
|
45601
|
+
TeX
|
|
45602
|
+
} = getDependencies();
|
|
45603
|
+
return [/*#__PURE__*/React.createElement(TeX, {
|
|
45604
|
+
key: "ln"
|
|
45605
|
+
}, i18n.doNotTranslate("\\ln")), "LN", i18n._("Natural logarithm")];
|
|
45606
|
+
}, () => {
|
|
45607
|
+
const {
|
|
45608
|
+
TeX
|
|
45609
|
+
} = getDependencies();
|
|
45610
|
+
return [/*#__PURE__*/React.createElement(TeX, {
|
|
45611
|
+
key: "log_b"
|
|
45612
|
+
}, i18n.doNotTranslate("\\log_b")), "LOG_B", i18n._("Logarithm with custom base")];
|
|
45613
|
+
}],
|
|
45614
|
+
"basic relations": [() => {
|
|
45615
|
+
const {
|
|
45616
|
+
TeX
|
|
45617
|
+
} = getDependencies();
|
|
45618
|
+
return [/*#__PURE__*/React.createElement(TeX, {
|
|
45619
|
+
key: "eq"
|
|
45620
|
+
}, "="), "EQUAL", i18n._("Equals sign")];
|
|
45621
|
+
}, () => {
|
|
45622
|
+
const {
|
|
45623
|
+
TeX
|
|
45624
|
+
} = getDependencies();
|
|
45625
|
+
return [/*#__PURE__*/React.createElement(TeX, {
|
|
45626
|
+
key: "lt"
|
|
45627
|
+
}, i18n.doNotTranslate("\\lt")), "LT", i18n._("Less than sign")];
|
|
45628
|
+
}, () => {
|
|
45629
|
+
const {
|
|
45630
|
+
TeX
|
|
45631
|
+
} = getDependencies();
|
|
45632
|
+
return [/*#__PURE__*/React.createElement(TeX, {
|
|
45633
|
+
key: "gt"
|
|
45634
|
+
}, i18n.doNotTranslate("\\gt")), "GT", i18n._("Greater than sign")];
|
|
45635
|
+
}],
|
|
45636
|
+
"advanced relations": [() => {
|
|
45637
|
+
const {
|
|
45638
|
+
TeX
|
|
45639
|
+
} = getDependencies();
|
|
45640
|
+
return [/*#__PURE__*/React.createElement(TeX, {
|
|
45641
|
+
key: "neq"
|
|
45642
|
+
}, i18n.doNotTranslate("\\neq")), "NEQ", i18n._("Not-equals sign")];
|
|
45643
|
+
}, () => {
|
|
45644
|
+
const {
|
|
45645
|
+
TeX
|
|
45646
|
+
} = getDependencies();
|
|
45647
|
+
return [/*#__PURE__*/React.createElement(TeX, {
|
|
45648
|
+
key: "leq"
|
|
45649
|
+
}, i18n.doNotTranslate("\\leq")), "LEQ", i18n._("Less than or equal to sign")];
|
|
45650
|
+
}, () => {
|
|
45651
|
+
const {
|
|
45652
|
+
TeX
|
|
45653
|
+
} = getDependencies();
|
|
45654
|
+
return [/*#__PURE__*/React.createElement(TeX, {
|
|
45655
|
+
key: "geq"
|
|
45656
|
+
}, i18n.doNotTranslate("\\geq")), "GEQ", i18n._("Greater than or equal to sign")];
|
|
45657
|
+
}]
|
|
45658
|
+
};
|
|
45659
|
+
const buttonSetsPropType = PropTypes.arrayOf(PropTypes.oneOf(_(buttonSets).keys()));
|
|
45660
|
+
class TexButtons extends React.Component {
|
|
45661
|
+
render() {
|
|
45662
|
+
// Always show buttonSets in the same order. Note: Technically it's ok
|
|
45663
|
+
// for _.keys() to return the keys in an arbitrary order, but in
|
|
45664
|
+
// practice, they will be ordered as listed above.
|
|
45665
|
+
const sortedButtonSets = _.sortBy(this.props.sets, setName => _.keys(buttonSets).indexOf(setName));
|
|
45666
|
+
const buttons = _(sortedButtonSets).map(setName => buttonSets[setName]);
|
|
45667
|
+
const buttonRows = _(buttons).map(row => row.map(symbGen => {
|
|
45668
|
+
// create a (component, thing we should send to mathquill) pair
|
|
45669
|
+
const symbol = symbGen(this.props);
|
|
45670
|
+
return /*#__PURE__*/React.createElement("button", {
|
|
45671
|
+
onClick: () => this.props.onInsert(symbol[1]),
|
|
45672
|
+
className: "tex-button"
|
|
45673
|
+
// @ts-expect-error - TS2533 - Object is possibly 'null' or 'undefined'. | TS2339 - Property 'key' does not exist on type 'boolean | ReactChild | ReactFragment | ReactPortal'.
|
|
45674
|
+
,
|
|
45675
|
+
key: symbol[0].key,
|
|
45676
|
+
type: "button",
|
|
45677
|
+
"aria-label": symbol[2]
|
|
45678
|
+
}, symbol[0]);
|
|
45679
|
+
}));
|
|
45680
|
+
const buttonPopup = _(buttonRows).map((row, i) => {
|
|
45681
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
45682
|
+
className: "clearfix tex-button-row",
|
|
45683
|
+
key: this.props.sets[i]
|
|
45684
|
+
}, row);
|
|
45685
|
+
});
|
|
45686
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
45687
|
+
className: `${this.props.className || ""} preview-measure`
|
|
45688
|
+
}, buttonPopup);
|
|
45689
|
+
}
|
|
45690
|
+
}
|
|
45691
|
+
TexButtons.buttonSets = buttonSets;
|
|
45692
|
+
TexButtons.buttonSetsType = buttonSetsPropType;
|
|
45693
|
+
|
|
45614
45694
|
var components = /*#__PURE__*/Object.freeze({
|
|
45615
45695
|
__proto__: null,
|
|
45616
45696
|
ButtonGroup: ButtonGroup,
|