@khanacademy/perseus 7.1.1 → 7.2.1
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/es/index.css +61 -61
- package/dist/es/index.js +100 -168
- package/dist/es/index.js.map +1 -1
- package/dist/index.css +61 -61
- package/dist/index.js +89 -126
- package/dist/index.js.map +1 -1
- package/dist/util.d.ts +7 -12
- package/dist/util.graphie.d.ts +6 -0
- package/dist/util.graphie.js.flow +14 -0
- package/dist/util.js.flow +7 -12
- package/dist/widgets/plotter.d.ts +47 -13
- package/dist/widgets/plotter.js.flow +47 -13
- package/package.json +2 -2
- package/src/__tests__/item-renderer.test.tsx +1 -1
- package/src/components/__stories__/image-loader.stories.tsx +1 -0
- package/src/components/graph.tsx +1 -0
- package/src/components/icon.tsx +1 -0
- package/src/components/image-loader.tsx +1 -0
- package/src/components/number-input.tsx +1 -0
- package/src/components/sortable.tsx +1 -0
- package/src/components/svg-image.tsx +1 -0
- package/src/components/tex-buttons.tsx +1 -0
- package/src/components/text-input.tsx +1 -0
- package/src/components/text-list-editor.tsx +1 -0
- package/src/components/zoomable.tsx +1 -0
- package/src/hints-renderer.tsx +1 -0
- package/src/index.ts +1 -0
- package/src/item-renderer.tsx +1 -0
- package/src/mixins/provide-keypad.tsx +1 -0
- package/src/multi-items/multi-renderer.tsx +1 -0
- package/src/renderer.tsx +1 -0
- package/src/server-item-renderer.tsx +1 -0
- package/src/styles/articles.less +8 -4
- package/src/styles/perseus-renderer.less +47 -38
- package/src/styles/util.less +1 -1
- package/src/styles/variables.boostrap.less +158 -182
- package/src/styles/variables.less +20 -20
- package/src/styles/variables.shared.less +162 -168
- package/src/styles/widgets/categorizer.less +1 -2
- package/src/styles/widgets/expression.less +7 -4
- package/src/styles/widgets/grapher.less +2 -1
- package/src/styles/widgets/image.less +3 -2
- package/src/styles/widgets/interactive-graph.less +4 -2
- package/src/styles/widgets/label-image.less +2 -1
- package/src/styles/widgets/matrix.less +11 -7
- package/src/styles/widgets/orderer.less +2 -1
- package/src/styles/widgets/passage.less +2 -1
- package/src/styles/widgets/plotter.less +4 -3
- package/src/styles/widgets/radio.less +4 -2
- package/src/styles/widgets/sortable.less +1 -1
- package/src/styles/widgets/table.less +2 -1
- package/src/styles/widgets/transformer.less +2 -1
- package/src/styles/widgets/unit.less +2 -1
- package/src/util.graphie.test.ts +45 -0
- package/src/util.graphie.ts +59 -0
- package/src/util.ts +8 -63
- package/src/widgets/__stories__/plotter.stories.tsx +27 -0
- package/src/widgets/__testdata__/plotter.testdata.ts +36 -0
- package/src/widgets/__tests__/__snapshots__/plotter.test.tsx.snap +863 -0
- package/src/widgets/__tests__/plotter.test.tsx +65 -0
- package/src/widgets/categorizer.tsx +1 -0
- package/src/widgets/graded-group-set.tsx +1 -0
- package/src/widgets/graded-group.tsx +1 -0
- package/src/widgets/interaction.tsx +1 -0
- package/src/widgets/label-image/marker.tsx +1 -0
- package/src/widgets/matcher.tsx +1 -0
- package/src/widgets/orderer.tsx +1 -0
- package/src/widgets/passage-ref-target.tsx +1 -0
- package/src/widgets/plotter.tsx +108 -98
- package/src/widgets/radio/base-radio.tsx +1 -0
- package/src/widgets/radio/choice-icon/choice-icon.tsx +1 -0
- package/src/widgets/sorter.tsx +1 -0
- package/src/widgets/transformer.tsx +1 -0
- package/tsconfig-build.tsbuildinfo +1 -1
package/dist/es/index.js
CHANGED
|
@@ -120,6 +120,7 @@ var dependencies = /*#__PURE__*/Object.freeze({
|
|
|
120
120
|
getDependencies: getDependencies
|
|
121
121
|
});
|
|
122
122
|
|
|
123
|
+
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
123
124
|
const prettyBig = {
|
|
124
125
|
fontSize: "150%"
|
|
125
126
|
};
|
|
@@ -1176,7 +1177,7 @@ var changeable = /*#__PURE__*/Object.freeze({
|
|
|
1176
1177
|
propTypes: propTypes
|
|
1177
1178
|
});
|
|
1178
1179
|
|
|
1179
|
-
/* eslint-disable @
|
|
1180
|
+
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
1180
1181
|
const textWidthCache = {};
|
|
1181
1182
|
function getTextWidth(text) {
|
|
1182
1183
|
if (!textWidthCache[text]) {
|
|
@@ -2945,8 +2946,6 @@ const defaultContext$2 = {
|
|
|
2945
2946
|
};
|
|
2946
2947
|
const context$1 = /*#__PURE__*/React.createContext(defaultContext$2);
|
|
2947
2948
|
|
|
2948
|
-
/* eslint-disable @babel/no-invalid-this, getter-return, one-var */
|
|
2949
|
-
let supportsPassive = false;
|
|
2950
2949
|
const svgLabelsRegex = /^web\+graphie:/;
|
|
2951
2950
|
// For offline exercises in the mobile app, we download the graphie data
|
|
2952
2951
|
// (svgs and localized data files) and serve them from the local file
|
|
@@ -2954,6 +2953,50 @@ const svgLabelsRegex = /^web\+graphie:/;
|
|
|
2954
2953
|
// in the perseus json with this `file+graphie` prefix to indicate that
|
|
2955
2954
|
// they should have the `file://` protocol instead of `https://`.
|
|
2956
2955
|
const svgLocalLabelsRegex$1 = /^file\+graphie:/;
|
|
2956
|
+
|
|
2957
|
+
// Sometimes other components want to download the actual image e.g. to
|
|
2958
|
+
// determine its size. Here, we transform an .svg-labels url into the
|
|
2959
|
+
// correct image url, and leave normal image urls alone
|
|
2960
|
+
function getRealImageUrl(graphieUrl) {
|
|
2961
|
+
if (isLabeledSVG(graphieUrl)) {
|
|
2962
|
+
return getSvgUrl(graphieUrl);
|
|
2963
|
+
}
|
|
2964
|
+
return graphieUrl;
|
|
2965
|
+
}
|
|
2966
|
+
function isLabeledSVG(graphieUrl) {
|
|
2967
|
+
return svgLabelsRegex.test(graphieUrl) || svgLocalLabelsRegex$1.test(graphieUrl);
|
|
2968
|
+
}
|
|
2969
|
+
|
|
2970
|
+
// For each graphie, there are two urls we need to download from. This gets
|
|
2971
|
+
// the base url without the suffix, and `getSvgUrl` and `getDataUrl` apply
|
|
2972
|
+
// appropriate suffixes to get the image and other data
|
|
2973
|
+
function getBaseUrl(graphieUrl) {
|
|
2974
|
+
return graphieUrl.replace(svgLabelsRegex, "https:").replace(svgLocalLabelsRegex$1, "file:");
|
|
2975
|
+
}
|
|
2976
|
+
function getSvgUrl(graphieUrl) {
|
|
2977
|
+
return getBaseUrl(graphieUrl) + ".svg";
|
|
2978
|
+
}
|
|
2979
|
+
function getDataUrl(graphieUrl) {
|
|
2980
|
+
return getBaseUrl(graphieUrl) + "-data.json";
|
|
2981
|
+
}
|
|
2982
|
+
async function getImageSizeModern(url) {
|
|
2983
|
+
const image = new Image();
|
|
2984
|
+
return new Promise((resolve, reject) => {
|
|
2985
|
+
// Handle the success case
|
|
2986
|
+
image.onload = () => {
|
|
2987
|
+
resolve([image.naturalWidth, image.naturalHeight]);
|
|
2988
|
+
};
|
|
2989
|
+
|
|
2990
|
+
// Handle the error case
|
|
2991
|
+
image.onerror = reject;
|
|
2992
|
+
|
|
2993
|
+
// Kick off the loading
|
|
2994
|
+
image.src = getRealImageUrl(url);
|
|
2995
|
+
});
|
|
2996
|
+
}
|
|
2997
|
+
|
|
2998
|
+
/* eslint-disable @babel/no-invalid-this, getter-return, one-var */
|
|
2999
|
+
let supportsPassive = false;
|
|
2957
3000
|
const nestedMap$2 = function nestedMap(children, func, context) {
|
|
2958
3001
|
if (Array.isArray(children)) {
|
|
2959
3002
|
// @ts-expect-error [FEI-5003] - TS2322 - Type '(M | readonly M[])[]' is not assignable to type 'M | readonly M[]'.
|
|
@@ -3618,21 +3661,6 @@ const supportsPassiveEvents = () => {
|
|
|
3618
3661
|
function captureScratchpadTouchStart$4(e) {
|
|
3619
3662
|
e.stopPropagation();
|
|
3620
3663
|
}
|
|
3621
|
-
async function getImageSizeModern(url) {
|
|
3622
|
-
const image = new Image();
|
|
3623
|
-
return new Promise((resolve, reject) => {
|
|
3624
|
-
// Handle the success case
|
|
3625
|
-
image.onload = () => {
|
|
3626
|
-
resolve([image.naturalWidth, image.naturalHeight]);
|
|
3627
|
-
};
|
|
3628
|
-
|
|
3629
|
-
// Handle the error case
|
|
3630
|
-
image.onerror = reject;
|
|
3631
|
-
|
|
3632
|
-
// Kick off the loading
|
|
3633
|
-
image.src = url;
|
|
3634
|
-
});
|
|
3635
|
-
}
|
|
3636
3664
|
function getImageSize(url, callback) {
|
|
3637
3665
|
const img = new Image();
|
|
3638
3666
|
img.onload = function () {
|
|
@@ -3662,32 +3690,6 @@ function getImageSize(url, callback) {
|
|
|
3662
3690
|
img.src = getRealImageUrl(url);
|
|
3663
3691
|
}
|
|
3664
3692
|
|
|
3665
|
-
// Sometimes other components want to download the actual image e.g. to
|
|
3666
|
-
// determine its size. Here, we transform an .svg-labels url into the
|
|
3667
|
-
// correct image url, and leave normal image urls alone
|
|
3668
|
-
function getRealImageUrl(url) {
|
|
3669
|
-
if (isLabeledSVG(url)) {
|
|
3670
|
-
return getSvgUrl(url);
|
|
3671
|
-
}
|
|
3672
|
-
return url;
|
|
3673
|
-
}
|
|
3674
|
-
function isLabeledSVG(url) {
|
|
3675
|
-
return svgLabelsRegex.test(url) || svgLocalLabelsRegex$1.test(url);
|
|
3676
|
-
}
|
|
3677
|
-
|
|
3678
|
-
// For each svg+labels, there are two urls we need to download from. This gets
|
|
3679
|
-
// the base url without the suffix, and `getSvgUrl` and `getDataUrl` apply
|
|
3680
|
-
// appropriate suffixes to get the image and other data
|
|
3681
|
-
function getBaseUrl(url) {
|
|
3682
|
-
return url.replace(svgLabelsRegex, "https:").replace(svgLocalLabelsRegex$1, "file:");
|
|
3683
|
-
}
|
|
3684
|
-
function getSvgUrl(url) {
|
|
3685
|
-
return getBaseUrl(url) + ".svg";
|
|
3686
|
-
}
|
|
3687
|
-
function getDataUrl(url) {
|
|
3688
|
-
return getBaseUrl(url) + "-data.json";
|
|
3689
|
-
}
|
|
3690
|
-
|
|
3691
3693
|
/**
|
|
3692
3694
|
* Gets the word right before where the textarea cursor is
|
|
3693
3695
|
*
|
|
@@ -3767,12 +3769,12 @@ const Util = {
|
|
|
3767
3769
|
supportsPassiveEvents,
|
|
3768
3770
|
captureScratchpadTouchStart: captureScratchpadTouchStart$4,
|
|
3769
3771
|
getImageSize,
|
|
3770
|
-
getImageSizeModern,
|
|
3771
|
-
getRealImageUrl,
|
|
3772
|
-
isLabeledSVG,
|
|
3773
|
-
getBaseUrl,
|
|
3774
|
-
getSvgUrl,
|
|
3775
|
-
getDataUrl,
|
|
3772
|
+
getImageSizeModern: getImageSizeModern,
|
|
3773
|
+
getRealImageUrl: getRealImageUrl,
|
|
3774
|
+
isLabeledSVG: isLabeledSVG,
|
|
3775
|
+
getBaseUrl: getBaseUrl,
|
|
3776
|
+
getSvgUrl: getSvgUrl,
|
|
3777
|
+
getDataUrl: getDataUrl,
|
|
3776
3778
|
textarea,
|
|
3777
3779
|
unescapeMathMode: unescapeMathMode$1,
|
|
3778
3780
|
random: random$1
|
|
@@ -20690,7 +20692,7 @@ MathOutput.defaultProps = {
|
|
|
20690
20692
|
onBlur: function () {}
|
|
20691
20693
|
};
|
|
20692
20694
|
|
|
20693
|
-
/* eslint-disable
|
|
20695
|
+
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
20694
20696
|
let lastId = 0;
|
|
20695
20697
|
function uniqueIdForInput(prefix = "input-") {
|
|
20696
20698
|
lastId++;
|
|
@@ -22140,36 +22142,7 @@ const scrollElementIntoView = (element, callback) => {
|
|
|
22140
22142
|
}, 0);
|
|
22141
22143
|
};
|
|
22142
22144
|
|
|
22143
|
-
|
|
22144
|
-
* SVG Icon React Component
|
|
22145
|
-
*
|
|
22146
|
-
* This component is designed to take in SVG paths and render icons based upon
|
|
22147
|
-
* them. If you are looking for an icon that we've used before you should look
|
|
22148
|
-
* in `icon-paths.js` which is a reference file for all the SVG paths that
|
|
22149
|
-
* we've used. You'll need to copy the object from that file into whichever
|
|
22150
|
-
* file you're using the icon and explicitly pass it in to the <Icon/> React
|
|
22151
|
-
* component.
|
|
22152
|
-
*
|
|
22153
|
-
* Sample usage:
|
|
22154
|
-
*
|
|
22155
|
-
* const dropdownIcon = `M5,6L0,0L10,0`;
|
|
22156
|
-
* <Icon icon={dropdownIcon} />
|
|
22157
|
-
*
|
|
22158
|
-
* Or:
|
|
22159
|
-
*
|
|
22160
|
-
* const dropdownIcon = {
|
|
22161
|
-
* path: `M5,6L0,0L10,0`,
|
|
22162
|
-
* height: 10,
|
|
22163
|
-
* width: 10,
|
|
22164
|
-
* };
|
|
22165
|
-
* <Icon icon={dropdownIcon} size={20} />
|
|
22166
|
-
*
|
|
22167
|
-
* A full list of all the existing icons can be seen here:
|
|
22168
|
-
* http://localhost:8080/react-sandbox/shared-styles-package/icon.jsx.fixture.js
|
|
22169
|
-
*
|
|
22170
|
-
* If you want to add an entirely new icon please read the note inside
|
|
22171
|
-
* the `icon-paths.js` file.
|
|
22172
|
-
*/
|
|
22145
|
+
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
22173
22146
|
// WARNING: This determines the *viewport* width and height, so a change here
|
|
22174
22147
|
// requires scaling the values of every SVG path passed in as a string
|
|
22175
22148
|
// without corresponding `width` and `height` values.
|
|
@@ -23769,7 +23742,7 @@ const WidgetJsonifyDeprecated = {
|
|
|
23769
23742
|
}
|
|
23770
23743
|
};
|
|
23771
23744
|
|
|
23772
|
-
/* eslint-disable
|
|
23745
|
+
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
23773
23746
|
class Categorizer extends React.Component {
|
|
23774
23747
|
constructor(..._args) {
|
|
23775
23748
|
super(..._args);
|
|
@@ -26782,7 +26755,7 @@ var Image$1 = {
|
|
|
26782
26755
|
isLintable: true
|
|
26783
26756
|
};
|
|
26784
26757
|
|
|
26785
|
-
/* eslint-disable @
|
|
26758
|
+
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
26786
26759
|
// @ts-expect-error [FEI-5003] - TS2339 - Property 'Label' does not exist on type 'typeof Graphie'.
|
|
26787
26760
|
const Label$1 = Graphie.Label;
|
|
26788
26761
|
// @ts-expect-error [FEI-5003] - TS2339 - Property 'Line' does not exist on type 'typeof Graphie'.
|
|
@@ -27384,7 +27357,7 @@ var Interactive = {
|
|
|
27384
27357
|
hidden: true
|
|
27385
27358
|
};
|
|
27386
27359
|
|
|
27387
|
-
/* eslint-disable
|
|
27360
|
+
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
27388
27361
|
const defaultBackgroundImage$2 = {
|
|
27389
27362
|
url: null
|
|
27390
27363
|
};
|
|
@@ -30920,11 +30893,7 @@ const styles$h = StyleSheet.create({
|
|
|
30920
30893
|
}
|
|
30921
30894
|
});
|
|
30922
30895
|
|
|
30923
|
-
|
|
30924
|
-
* Controlled question image marker, rendered as a styled button element.
|
|
30925
|
-
*
|
|
30926
|
-
* The target for labeling question image with answers.
|
|
30927
|
-
*/
|
|
30896
|
+
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
30928
30897
|
class Marker extends React.Component {
|
|
30929
30898
|
constructor(...args) {
|
|
30930
30899
|
super(...args);
|
|
@@ -32790,7 +32759,7 @@ const styles$e = StyleSheet.create({
|
|
|
32790
32759
|
}
|
|
32791
32760
|
});
|
|
32792
32761
|
|
|
32793
|
-
/* eslint-disable
|
|
32762
|
+
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
32794
32763
|
const {
|
|
32795
32764
|
shuffle: shuffle$1,
|
|
32796
32765
|
seededRNG
|
|
@@ -38102,30 +38071,15 @@ var PassageRefTarget$1 = {
|
|
|
38102
38071
|
isLintable: true
|
|
38103
38072
|
};
|
|
38104
38073
|
|
|
38105
|
-
/* eslint-disable
|
|
38074
|
+
/* eslint-disable react/no-unsafe */
|
|
38106
38075
|
const {
|
|
38107
38076
|
deepEq: deepEq$1
|
|
38108
38077
|
} = Util;
|
|
38109
|
-
const BAR = "bar"
|
|
38110
|
-
|
|
38111
|
-
|
|
38112
|
-
|
|
38113
|
-
|
|
38114
|
-
({
|
|
38115
|
-
type: PropTypes.oneOf([BAR, LINE, PIC, HISTOGRAM, DOTPLOT]),
|
|
38116
|
-
labels: PropTypes.arrayOf(PropTypes.string),
|
|
38117
|
-
categories: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.number, PropTypes.string])),
|
|
38118
|
-
scaleY: PropTypes.number,
|
|
38119
|
-
maxY: PropTypes.number,
|
|
38120
|
-
snapsPerLine: PropTypes.number,
|
|
38121
|
-
picSize: PropTypes.number,
|
|
38122
|
-
pixBoxHeight: PropTypes.number,
|
|
38123
|
-
picUrl: PropTypes.string,
|
|
38124
|
-
plotDimensions: PropTypes.arrayOf(PropTypes.number),
|
|
38125
|
-
labelInterval: PropTypes.number,
|
|
38126
|
-
starting: PropTypes.arrayOf(PropTypes.number),
|
|
38127
|
-
static: PropTypes.bool
|
|
38128
|
-
});
|
|
38078
|
+
const BAR = "bar";
|
|
38079
|
+
const LINE = "line";
|
|
38080
|
+
const PIC = "pic";
|
|
38081
|
+
const HISTOGRAM = "histogram";
|
|
38082
|
+
const DOTPLOT = "dotplot";
|
|
38129
38083
|
class Plotter extends React.Component {
|
|
38130
38084
|
constructor(..._args) {
|
|
38131
38085
|
super(..._args);
|
|
@@ -38164,11 +38118,11 @@ class Plotter extends React.Component {
|
|
|
38164
38118
|
self.graphie = graphie;
|
|
38165
38119
|
self.graphie.pics = [];
|
|
38166
38120
|
self.graphie.dotTicks = [];
|
|
38167
|
-
const isBar = self.props.type === BAR
|
|
38168
|
-
|
|
38169
|
-
|
|
38170
|
-
|
|
38171
|
-
|
|
38121
|
+
const isBar = self.props.type === BAR;
|
|
38122
|
+
const isLine = self.props.type === LINE;
|
|
38123
|
+
const isPic = self.props.type === PIC;
|
|
38124
|
+
const isHistogram = self.props.type === HISTOGRAM;
|
|
38125
|
+
const isDotplot = self.props.type === DOTPLOT;
|
|
38172
38126
|
const isTiledPlot = isPic || isDotplot;
|
|
38173
38127
|
const config = {};
|
|
38174
38128
|
const c = config; // c for short
|
|
@@ -38229,9 +38183,7 @@ class Plotter extends React.Component {
|
|
|
38229
38183
|
|
|
38230
38184
|
// TODO(michaelpolyak): Handle other plot types: Dot, Histogram, Line.
|
|
38231
38185
|
if (isMobile && (isBar || isTiledPlot)) {
|
|
38232
|
-
const maxCategoryHeight = Math.max(0,
|
|
38233
|
-
// @ts-expect-error [FEI-5003] - TS2345 - Argument of type 'unknown' is not assignable to parameter of type 'number'.
|
|
38234
|
-
...Object.values(self.state.categoryHeights));
|
|
38186
|
+
const maxCategoryHeight = Math.max(0, ...Object.values(self.state.categoryHeights));
|
|
38235
38187
|
if (maxCategoryHeight) {
|
|
38236
38188
|
// Account for bottom label position, height.
|
|
38237
38189
|
let offsetY = 25;
|
|
@@ -38284,7 +38236,7 @@ class Plotter extends React.Component {
|
|
|
38284
38236
|
});
|
|
38285
38237
|
}
|
|
38286
38238
|
}
|
|
38287
|
-
if ((isBar || isLine) && isMobile) {
|
|
38239
|
+
if ((isBar || isLine) && isMobile && !this.props.static) {
|
|
38288
38240
|
self.graphie.dragPrompt = graphie.label([c.dimX / 2, c.dimY / 2], i18n._("Drag handles to make graph"), "center", false).css("font-weight", "bold").css("color", KhanColors.KA_GREEN).css("display", "none");
|
|
38289
38241
|
}
|
|
38290
38242
|
self.setupCategories(config);
|
|
@@ -38533,8 +38485,8 @@ class Plotter extends React.Component {
|
|
|
38533
38485
|
config.graph.bars[i].scale(1, Math.max(isMobile ? 0.2 : 0.01, height / config.scaleY), center[0], center[1]);
|
|
38534
38486
|
if (isHistogram) {
|
|
38535
38487
|
// Scale dividers between buckets
|
|
38536
|
-
const leftDivider = config.graph.dividers[i - 1]
|
|
38537
|
-
|
|
38488
|
+
const leftDivider = config.graph.dividers[i - 1];
|
|
38489
|
+
const rightDivider = config.graph.dividers[i];
|
|
38538
38490
|
if (leftDivider) {
|
|
38539
38491
|
const divHeight = Math.min(self.state.values[i - 1], height);
|
|
38540
38492
|
leftDivider.scale(1, Math.max(0.01, divHeight / config.scaleY), center[0], center[1]);
|
|
@@ -38859,38 +38811,13 @@ class Plotter extends React.Component {
|
|
|
38859
38811
|
return Plotter.validate(this.getUserInput(), rubric);
|
|
38860
38812
|
};
|
|
38861
38813
|
}
|
|
38862
|
-
render() {
|
|
38863
|
-
// TODO(kevinb) actually compute the size of the graphie correctly and
|
|
38864
|
-
// make it that size so we don't have to add extra padding. The value
|
|
38865
|
-
// was determined by eye-balling the layout. :(
|
|
38866
|
-
const paddingForBottomLabel = 75;
|
|
38867
|
-
const style = {
|
|
38868
|
-
marginBottom: this.props.labels[0] ? paddingForBottomLabel : 0
|
|
38869
|
-
};
|
|
38870
|
-
return /*#__PURE__*/React.createElement("div", {
|
|
38871
|
-
className: "perseus-widget-plotter graphie " + ClassNames.INTERACTIVE
|
|
38872
|
-
// eslint-disable-next-line react/no-string-refs
|
|
38873
|
-
,
|
|
38874
|
-
ref: "graphieDiv",
|
|
38875
|
-
style: style
|
|
38876
|
-
});
|
|
38877
|
-
}
|
|
38878
|
-
componentDidUpdate(prevProps, prevState) {
|
|
38879
|
-
this.shouldSetupGraphie = this.shouldSetupGraphie || !_.isEqual(this.state.categoryHeights, prevState.categoryHeights);
|
|
38880
|
-
if (this.shouldSetupGraphie) {
|
|
38881
|
-
this.setupGraphie(prevState);
|
|
38882
|
-
}
|
|
38883
|
-
}
|
|
38884
38814
|
componentDidMount() {
|
|
38885
38815
|
this._isMounted = true;
|
|
38886
38816
|
this.setupGraphie(this.state);
|
|
38887
38817
|
}
|
|
38888
38818
|
UNSAFE_componentWillReceiveProps(nextProps) {
|
|
38889
38819
|
const props = ["type", "labels", "categories", "scaleY", "maxY", "snapsPerLine", "picUrl", "labelInterval", "static"];
|
|
38890
|
-
this.shouldSetupGraphie = _.any(props,
|
|
38891
|
-
// @ts-expect-error [FEI-5003] - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
38892
|
-
return !_.isEqual(this.props[prop], nextProps[prop]);
|
|
38893
|
-
}, this);
|
|
38820
|
+
this.shouldSetupGraphie = _.any(props, prop => !_.isEqual(this.props[prop], nextProps[prop]), this);
|
|
38894
38821
|
if (!_.isEqual(this.props.starting, nextProps.starting) && !_.isEqual(this.state.values, nextProps.starting)) {
|
|
38895
38822
|
this.shouldSetupGraphie = true;
|
|
38896
38823
|
this.setState({
|
|
@@ -38898,16 +38825,32 @@ class Plotter extends React.Component {
|
|
|
38898
38825
|
});
|
|
38899
38826
|
}
|
|
38900
38827
|
}
|
|
38828
|
+
componentDidUpdate(prevProps, prevState) {
|
|
38829
|
+
this.shouldSetupGraphie = this.shouldSetupGraphie || !_.isEqual(this.state.categoryHeights, prevState.categoryHeights);
|
|
38830
|
+
if (this.shouldSetupGraphie) {
|
|
38831
|
+
this.setupGraphie(prevState);
|
|
38832
|
+
}
|
|
38833
|
+
}
|
|
38901
38834
|
componentWillUnmount() {
|
|
38902
38835
|
this._isMounted = false;
|
|
38903
38836
|
}
|
|
38837
|
+
render() {
|
|
38838
|
+
// TODO(kevinb) actually compute the size of the graphie correctly and
|
|
38839
|
+
// make it that size so we don't have to add extra padding. The value
|
|
38840
|
+
// was determined by eye-balling the layout. :(
|
|
38841
|
+
const paddingForBottomLabel = 75;
|
|
38842
|
+
const style = {
|
|
38843
|
+
marginBottom: this.props.labels[0] ? paddingForBottomLabel : 0
|
|
38844
|
+
};
|
|
38845
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
38846
|
+
className: "perseus-widget-plotter graphie " + ClassNames.INTERACTIVE
|
|
38847
|
+
// eslint-disable-next-line react/no-string-refs
|
|
38848
|
+
,
|
|
38849
|
+
ref: "graphieDiv",
|
|
38850
|
+
style: style
|
|
38851
|
+
});
|
|
38852
|
+
}
|
|
38904
38853
|
}
|
|
38905
|
-
Plotter.propTypes = {
|
|
38906
|
-
onChange: PropTypes.func.isRequired,
|
|
38907
|
-
trackInteraction: PropTypes.func.isRequired
|
|
38908
|
-
// TODO(alex): Figure out why lint chokes on this line
|
|
38909
|
-
// ...widgetPropTypes,
|
|
38910
|
-
};
|
|
38911
38854
|
Plotter.defaultProps = {
|
|
38912
38855
|
type: BAR,
|
|
38913
38856
|
labels: ["", ""],
|
|
@@ -39878,6 +39821,7 @@ var Simulator$1 = {
|
|
|
39878
39821
|
hidden: true
|
|
39879
39822
|
};
|
|
39880
39823
|
|
|
39824
|
+
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
39881
39825
|
const {
|
|
39882
39826
|
shuffle
|
|
39883
39827
|
} = Util;
|
|
@@ -43913,17 +43857,7 @@ registerWidgets(allWidgets);
|
|
|
43913
43857
|
const ItemVersion = getVersionVector();
|
|
43914
43858
|
ItemVersion["::renderer::"] = version.itemDataVersion;
|
|
43915
43859
|
|
|
43916
|
-
|
|
43917
|
-
* A mixin that renders a custom software keypad in additional to the base
|
|
43918
|
-
* component. The base component will receive blur events when the keypad is
|
|
43919
|
-
* dismissed and can access the keypad element itself so as to manage its
|
|
43920
|
-
* activation and dismissal.
|
|
43921
|
-
*
|
|
43922
|
-
* TODO(charlie): This would make a nicer higher-order component, except that
|
|
43923
|
-
* we need to expose methods on the base component (i.e., `ItemRenderer`). When
|
|
43924
|
-
* `ItemRenderer` and friends are written as ES6 Classes, we can have them
|
|
43925
|
-
* extend a `ProvideKeypad` component instead of using this mixin.
|
|
43926
|
-
*/
|
|
43860
|
+
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
43927
43861
|
// NOTE: This is not a real component. It's a collection of methods used to
|
|
43928
43862
|
// create and manage a Keypad instances.
|
|
43929
43863
|
// TODO(LP-10789): replace this with a React Context object to pass information
|
|
@@ -46873,9 +46807,7 @@ const EditorJsonify = {
|
|
|
46873
46807
|
}
|
|
46874
46808
|
};
|
|
46875
46809
|
|
|
46876
|
-
|
|
46877
|
-
* Main entry point
|
|
46878
|
-
*/
|
|
46810
|
+
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
46879
46811
|
const apiVersion = version.apiVersion;
|
|
46880
46812
|
const itemDataVersion = version.itemDataVersion;
|
|
46881
46813
|
|