@khanacademy/perseus 57.2.0 → 57.2.2
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/dist/es/index.css +1 -2
- package/dist/es/index.js +71 -67
- package/dist/es/index.js.map +1 -1
- package/dist/index.css +1 -2
- package/dist/index.js +71 -68
- package/dist/index.js.map +1 -1
- package/dist/widgets/interactive-graphs/graphs/components/movable-point-view.d.ts +0 -1
- package/dist/widgets/interactive-graphs/graphs/utils.d.ts +1 -1
- package/dist/widgets/interactive-graphs/locked-figures/utils.d.ts +1 -0
- package/package.json +12 -11
- package/dist/shared-utils/add-library-version-to-perseus-debug.d.ts +0 -9
package/dist/es/index.css
CHANGED
|
@@ -1078,7 +1078,7 @@ div.graphie {
|
|
|
1078
1078
|
font-size: 14px;
|
|
1079
1079
|
}
|
|
1080
1080
|
.framework-perseus .number-input {
|
|
1081
|
-
border: 1px solid #
|
|
1081
|
+
border: 1px solid #909296;
|
|
1082
1082
|
border-radius: 5px;
|
|
1083
1083
|
margin: 0;
|
|
1084
1084
|
padding: 5px 0;
|
|
@@ -2966,7 +2966,6 @@ html body .mq-editable-field .mq-selection .mq-nthroot-container * {
|
|
|
2966
2966
|
--movable-point-hover-expansion: 2px;
|
|
2967
2967
|
--movable-point-focus-ring-offset: 2px;
|
|
2968
2968
|
|
|
2969
|
-
--movable-line-stroke-color: var(--mafs-blue);
|
|
2970
2969
|
--movable-line-stroke-weight: 2px;
|
|
2971
2970
|
--movable-line-stroke-weight-active: 4px;
|
|
2972
2971
|
overflow: visible !important;
|
package/dist/es/index.js
CHANGED
|
@@ -27,7 +27,7 @@ import { KeypadContext } from '@khanacademy/keypad-context';
|
|
|
27
27
|
import { TextField } from '@khanacademy/wonder-blocks-form';
|
|
28
28
|
import { entries, UnreachableCaseError, keys } from '@khanacademy/wonder-stuff-core';
|
|
29
29
|
import { CircularSpinner } from '@khanacademy/wonder-blocks-progress-spinner';
|
|
30
|
-
import { point, KhanMath,
|
|
30
|
+
import { point, KhanMath, vector as vector$3, number, line, geometry, angles, coefficients } from '@khanacademy/kmath';
|
|
31
31
|
import _classPrivateFieldLooseBase from '@babel/runtime/helpers/classPrivateFieldLooseBase';
|
|
32
32
|
import _classPrivateFieldLooseKey from '@babel/runtime/helpers/classPrivateFieldLooseKey';
|
|
33
33
|
import SimpleMarkdown from '@khanacademy/simple-markdown';
|
|
@@ -48,6 +48,7 @@ import { Popper } from 'react-popper';
|
|
|
48
48
|
import IconButton from '@khanacademy/wonder-blocks-icon-button';
|
|
49
49
|
import cornersOutIcon from '@phosphor-icons/core/regular/corners-out.svg';
|
|
50
50
|
import Link from '@khanacademy/wonder-blocks-link';
|
|
51
|
+
import { addLibraryVersionToPerseusDebug } from '@khanacademy/perseus-utils';
|
|
51
52
|
|
|
52
53
|
/**
|
|
53
54
|
* The translated strings that are used to render Perseus.
|
|
@@ -767,9 +768,12 @@ class InnerMathInput extends React.Component {
|
|
|
767
768
|
// a keyboard event is "keydown" type.
|
|
768
769
|
// In react without WonderBlocks, "enter" or "space" keydown events
|
|
769
770
|
// are also "click" events, differentiated by "detail".
|
|
770
|
-
if (e.type === "click") {
|
|
771
|
+
if ((e == null ? void 0 : e.type) === "click") {
|
|
771
772
|
this.focus();
|
|
772
773
|
}
|
|
774
|
+
if (key === "DISMISS") {
|
|
775
|
+
this.closeKeypad();
|
|
776
|
+
}
|
|
773
777
|
};
|
|
774
778
|
}
|
|
775
779
|
componentDidMount() {
|
|
@@ -829,10 +833,9 @@ class InnerMathInput extends React.Component {
|
|
|
829
833
|
onFocus: () => this.focus(),
|
|
830
834
|
onBlur: () => this.blur()
|
|
831
835
|
}), /*#__PURE__*/React.createElement(Popover, {
|
|
832
|
-
rootBoundary: "document",
|
|
833
836
|
opened: this.state.keypadOpen,
|
|
834
|
-
onClose: () => this.closeKeypad(),
|
|
835
837
|
dismissEnabled: true,
|
|
838
|
+
rootBoundary: "document",
|
|
836
839
|
"aria-label": this.context.strings.mathInputTitle,
|
|
837
840
|
"aria-describedby": `popover-content-${popoverContentUniqueId}`,
|
|
838
841
|
content: () => {
|
|
@@ -841,7 +844,6 @@ class InnerMathInput extends React.Component {
|
|
|
841
844
|
id: `popover-content-${popoverContentUniqueId}`,
|
|
842
845
|
style: a11y.srOnly
|
|
843
846
|
}, this.context.strings.mathInputDescription), /*#__PURE__*/React.createElement(PopoverContentCore, {
|
|
844
|
-
closeButtonVisible: true,
|
|
845
847
|
style: styles$D.popoverContent
|
|
846
848
|
}, /*#__PURE__*/React.createElement(DesktopKeypad, _extends({
|
|
847
849
|
onAnalyticsEvent: this.props.onAnalyticsEvent,
|
|
@@ -849,7 +851,9 @@ class InnerMathInput extends React.Component {
|
|
|
849
851
|
onClickKey: this.handleKeypadPress,
|
|
850
852
|
cursorContext: this.state.cursorContext,
|
|
851
853
|
convertDotToTimes: this.props.convertDotToTimes
|
|
852
|
-
}, (_this$props$keypadBut = this.props.keypadButtonSets) != null ? _this$props$keypadBut : mapButtonSets((_this$props = this.props) == null ? void 0 : _this$props.buttonSets)
|
|
854
|
+
}, (_this$props$keypadBut = this.props.keypadButtonSets) != null ? _this$props$keypadBut : mapButtonSets((_this$props = this.props) == null ? void 0 : _this$props.buttonSets), {
|
|
855
|
+
showDismiss: true
|
|
856
|
+
}))));
|
|
853
857
|
}
|
|
854
858
|
}, this.props.buttonsVisible === "never" ? /*#__PURE__*/React.createElement(MathInputIcon, {
|
|
855
859
|
hovered: false,
|
|
@@ -1003,7 +1007,6 @@ const styles$D = StyleSheet.create({
|
|
|
1003
1007
|
},
|
|
1004
1008
|
popoverContent: {
|
|
1005
1009
|
padding: 0,
|
|
1006
|
-
paddingBottom: spacing.xxSmall_6,
|
|
1007
1010
|
maxWidth: "initial"
|
|
1008
1011
|
}
|
|
1009
1012
|
});
|
|
@@ -3021,6 +3024,7 @@ Zoom.prototype.zoomImage = function () {
|
|
|
3021
3024
|
img.src = this._targetImage.src;
|
|
3022
3025
|
img.alt = this._targetImage.alt;
|
|
3023
3026
|
img.tabIndex = 0;
|
|
3027
|
+
img.role = "button";
|
|
3024
3028
|
this.$zoomedImage = $zoomedImage;
|
|
3025
3029
|
};
|
|
3026
3030
|
Zoom.prototype._zoomOriginal = function () {
|
|
@@ -7980,6 +7984,7 @@ var createRoot;
|
|
|
7980
7984
|
var m = ReactDOM__default;
|
|
7981
7985
|
if (process.env.NODE_ENV === 'production') {
|
|
7982
7986
|
createRoot = m.createRoot;
|
|
7987
|
+
m.hydrateRoot;
|
|
7983
7988
|
} else {
|
|
7984
7989
|
var i = m.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
|
|
7985
7990
|
createRoot = function(c, o) {
|
|
@@ -15810,12 +15815,19 @@ class ImageLoader extends React.Component {
|
|
|
15810
15815
|
};
|
|
15811
15816
|
}
|
|
15812
15817
|
const staticUrl = getDependencies().staticUrl;
|
|
15818
|
+
|
|
15819
|
+
// If the image is interactive, it should have a role of "button"
|
|
15820
|
+
// to indicate that it is interactive.
|
|
15821
|
+
const imageRole = imgProps.onClick !== null ? "button" : "img";
|
|
15813
15822
|
return (
|
|
15814
15823
|
/*#__PURE__*/
|
|
15815
|
-
//
|
|
15824
|
+
// (LEMS-2871) NOTE: This image IS interactive if it requires zooming, and LevelAccess specifically requested
|
|
15825
|
+
// that the role and tabIndex be set here. When users interact with the image on mobile, it will zoom in.
|
|
15826
|
+
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
|
|
15816
15827
|
React.createElement("img", _extends({
|
|
15817
15828
|
// eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex -- TODO(LEMS-2871): Address a11y error
|
|
15818
15829
|
tabIndex: 0,
|
|
15830
|
+
role: imageRole,
|
|
15819
15831
|
src: staticUrl(src),
|
|
15820
15832
|
onKeyUp: onKeyUp,
|
|
15821
15833
|
onKeyDown: onKeyDown
|
|
@@ -28928,7 +28940,28 @@ const LockedEllipse = props => {
|
|
|
28928
28940
|
}));
|
|
28929
28941
|
};
|
|
28930
28942
|
|
|
28943
|
+
function clampDomain(domain, graphBounds) {
|
|
28944
|
+
// If the domain is invalid, return the graph bounds
|
|
28945
|
+
if (domain[0] > domain[1]) {
|
|
28946
|
+
return graphBounds;
|
|
28947
|
+
}
|
|
28948
|
+
|
|
28949
|
+
// If the domain is outside the graph bounds, return null
|
|
28950
|
+
if (domain[0] < graphBounds[0] && domain[1] < graphBounds[0] || domain[0] > graphBounds[1] && domain[1] > graphBounds[1]) {
|
|
28951
|
+
return null;
|
|
28952
|
+
}
|
|
28953
|
+
|
|
28954
|
+
// Clamp the function to the bounds of the graph to prevent memory
|
|
28955
|
+
// leaks when the domain is set to something like [-Infinity, Infinity].
|
|
28956
|
+
const min = Math.max(domain[0], graphBounds[0]);
|
|
28957
|
+
const max = Math.min(domain[1], graphBounds[1]);
|
|
28958
|
+
return [min, max];
|
|
28959
|
+
}
|
|
28960
|
+
|
|
28931
28961
|
const LockedFunction = props => {
|
|
28962
|
+
const {
|
|
28963
|
+
range
|
|
28964
|
+
} = useGraphConfig();
|
|
28932
28965
|
const [equation, setEquation] = useState();
|
|
28933
28966
|
const {
|
|
28934
28967
|
color,
|
|
@@ -28938,8 +28971,7 @@ const LockedFunction = props => {
|
|
|
28938
28971
|
} = props;
|
|
28939
28972
|
const plotProps = {
|
|
28940
28973
|
color: lockedFigureColors[color],
|
|
28941
|
-
style: strokeStyle
|
|
28942
|
-
domain
|
|
28974
|
+
style: strokeStyle
|
|
28943
28975
|
};
|
|
28944
28976
|
const hasAria = !!props.ariaLabel;
|
|
28945
28977
|
useEffect(() => {
|
|
@@ -28950,6 +28982,12 @@ const LockedFunction = props => {
|
|
|
28950
28982
|
if (typeof equation === "undefined") {
|
|
28951
28983
|
return null;
|
|
28952
28984
|
}
|
|
28985
|
+
const clampedDomain = directionalAxis === "x" ? clampDomain(domain, range[0]) : clampDomain(domain, range[1]);
|
|
28986
|
+
|
|
28987
|
+
// The domain entirely is outside the bounds of the graph. Don't render.
|
|
28988
|
+
if (clampedDomain === null) {
|
|
28989
|
+
return null;
|
|
28990
|
+
}
|
|
28953
28991
|
return /*#__PURE__*/React.createElement("g", {
|
|
28954
28992
|
className: "locked-function",
|
|
28955
28993
|
"aria-label": hasAria ? props.ariaLabel : undefined,
|
|
@@ -28958,11 +28996,13 @@ const LockedFunction = props => {
|
|
|
28958
28996
|
}, directionalAxis === "x" && /*#__PURE__*/React.createElement(Plot$2.OfX, _extends({
|
|
28959
28997
|
y: x => equation.eval({
|
|
28960
28998
|
x
|
|
28961
|
-
})
|
|
28999
|
+
}),
|
|
29000
|
+
domain: clampedDomain
|
|
28962
29001
|
}, plotProps)), directionalAxis === "y" && /*#__PURE__*/React.createElement(Plot$2.OfY, _extends({
|
|
28963
29002
|
x: y => equation.eval({
|
|
28964
29003
|
y
|
|
28965
|
-
})
|
|
29004
|
+
}),
|
|
29005
|
+
domain: clampedDomain
|
|
28966
29006
|
}, plotProps)));
|
|
28967
29007
|
};
|
|
28968
29008
|
|
|
@@ -30344,15 +30384,14 @@ const hitboxSizePx = 48;
|
|
|
30344
30384
|
// function with no state or effects) that renders the SVG for a movable point
|
|
30345
30385
|
// on an interactive graph.
|
|
30346
30386
|
const MovablePointView = /*#__PURE__*/forwardRef((props, hitboxRef) => {
|
|
30347
|
-
var _Object$entries$find$, _Object$entries$find;
|
|
30348
30387
|
const {
|
|
30349
30388
|
markings,
|
|
30350
30389
|
showTooltips,
|
|
30351
|
-
interactiveColor
|
|
30390
|
+
interactiveColor,
|
|
30391
|
+
disableKeyboardInteraction
|
|
30352
30392
|
} = useGraphConfig();
|
|
30353
30393
|
const {
|
|
30354
30394
|
point,
|
|
30355
|
-
color: color$1 = interactiveColor,
|
|
30356
30395
|
dragging,
|
|
30357
30396
|
focused,
|
|
30358
30397
|
cursor,
|
|
@@ -30360,9 +30399,14 @@ const MovablePointView = /*#__PURE__*/forwardRef((props, hitboxRef) => {
|
|
|
30360
30399
|
onClick = () => {}
|
|
30361
30400
|
} = props;
|
|
30362
30401
|
|
|
30363
|
-
// WB Tooltip requires a color name for the background color.
|
|
30364
|
-
//
|
|
30365
|
-
|
|
30402
|
+
// WB Tooltip requires a WB color name for the background color.
|
|
30403
|
+
// We use the blue color when the points are interactive, and
|
|
30404
|
+
// offBlack64 when they are disabled.
|
|
30405
|
+
// Note: The disabled point color is offBlack50 to contrast with
|
|
30406
|
+
// the interactive blue color, but the tooltip background has to be
|
|
30407
|
+
// darker to contrast with its white text - using offBlack64.
|
|
30408
|
+
const wbColorName = disableKeyboardInteraction ? "fadedOffBlack64" // not see-through
|
|
30409
|
+
: "blue";
|
|
30366
30410
|
const pointClasses = classNames("movable-point", dragging && "movable-point--dragging", showFocusRing && "movable-point--focus");
|
|
30367
30411
|
const [[x, y]] = useTransformVectorsToPixels(point);
|
|
30368
30412
|
const showHairlines = (dragging || focused) && markings !== "none";
|
|
@@ -30375,7 +30419,7 @@ const MovablePointView = /*#__PURE__*/forwardRef((props, hitboxRef) => {
|
|
|
30375
30419
|
ref: hitboxRef,
|
|
30376
30420
|
className: pointClasses,
|
|
30377
30421
|
style: {
|
|
30378
|
-
"--movable-point-color":
|
|
30422
|
+
"--movable-point-color": interactiveColor,
|
|
30379
30423
|
cursor
|
|
30380
30424
|
},
|
|
30381
30425
|
"data-testid": "movable-point",
|
|
@@ -30402,7 +30446,7 @@ const MovablePointView = /*#__PURE__*/forwardRef((props, hitboxRef) => {
|
|
|
30402
30446
|
cx: x,
|
|
30403
30447
|
cy: y,
|
|
30404
30448
|
style: {
|
|
30405
|
-
fill:
|
|
30449
|
+
fill: interactiveColor
|
|
30406
30450
|
},
|
|
30407
30451
|
"data-testid": "movable-point__center"
|
|
30408
30452
|
}));
|
|
@@ -30434,7 +30478,6 @@ function useControlPoint(params) {
|
|
|
30434
30478
|
ariaDescribedBy,
|
|
30435
30479
|
ariaLabel,
|
|
30436
30480
|
ariaLive = "polite",
|
|
30437
|
-
color,
|
|
30438
30481
|
constrain = p => snap(snapStep, p),
|
|
30439
30482
|
cursor,
|
|
30440
30483
|
forwardedRef = noop$1,
|
|
@@ -30497,6 +30540,7 @@ function useControlPoint(params) {
|
|
|
30497
30540
|
"aria-describedby": ariaDescribedBy,
|
|
30498
30541
|
"aria-label": pointAriaLabel,
|
|
30499
30542
|
"aria-live": ariaLive,
|
|
30543
|
+
"aria-disabled": disableKeyboardInteraction,
|
|
30500
30544
|
onFocus: event => {
|
|
30501
30545
|
onFocus(event);
|
|
30502
30546
|
setFocused(true);
|
|
@@ -30516,7 +30560,6 @@ function useControlPoint(params) {
|
|
|
30516
30560
|
point: point,
|
|
30517
30561
|
dragging: dragging,
|
|
30518
30562
|
focused: focused,
|
|
30519
|
-
color: color,
|
|
30520
30563
|
ref: visiblePointRef,
|
|
30521
30564
|
showFocusRing: focused
|
|
30522
30565
|
});
|
|
@@ -30660,6 +30703,7 @@ const Line$1 = props => {
|
|
|
30660
30703
|
"aria-label": ariaLabel,
|
|
30661
30704
|
"aria-describedby": ariaDescribedBy,
|
|
30662
30705
|
"aria-live": ariaLive,
|
|
30706
|
+
"aria-disabled": disableKeyboardInteraction,
|
|
30663
30707
|
className: "movable-line",
|
|
30664
30708
|
"data-testid": "movable-line",
|
|
30665
30709
|
style: {
|
|
@@ -31203,6 +31247,7 @@ function MovableCircle(props) {
|
|
|
31203
31247
|
"aria-label": ariaLabel,
|
|
31204
31248
|
"aria-describedby": ariaDescribedBy,
|
|
31205
31249
|
"aria-live": "polite",
|
|
31250
|
+
"aria-disabled": disableKeyboardInteraction,
|
|
31206
31251
|
ref: draggableRef,
|
|
31207
31252
|
role: "button",
|
|
31208
31253
|
tabIndex: disableKeyboardInteraction ? -1 : 0,
|
|
@@ -33079,7 +33124,8 @@ const LimitedPolygonGraph = statefulProps => {
|
|
|
33079
33124
|
// Accessibility-related fields
|
|
33080
33125
|
role: "button",
|
|
33081
33126
|
"aria-label": srPolygonGraphPoints ? `${srPolygonElementsNum} ${srPolygonGraphPoints}` : srPolygonElementsNum,
|
|
33082
|
-
"aria-live": ariaLives[0]
|
|
33127
|
+
"aria-live": ariaLives[0],
|
|
33128
|
+
"aria-disabled": disableKeyboardInteraction
|
|
33083
33129
|
}
|
|
33084
33130
|
}), points.map((point, i) => {
|
|
33085
33131
|
const angleId = `${id}-angle-${i}`;
|
|
@@ -34363,7 +34409,7 @@ const MafsGraph = props => {
|
|
|
34363
34409
|
handleKeyboardEvent(event, state, dispatch);
|
|
34364
34410
|
},
|
|
34365
34411
|
"aria-label": fullGraphAriaLabel,
|
|
34366
|
-
"aria-describedby": describedByIds(fullGraphAriaDescription && descriptionId, interactiveElementsDescription && interactiveElementsDescriptionId, isUnlimitedGraphState(state) && unlimitedGraphKeyboardPromptId, state.type !== "none" && instructionsId),
|
|
34412
|
+
"aria-describedby": describedByIds(fullGraphAriaDescription && descriptionId, interactiveElementsDescription && interactiveElementsDescriptionId, isUnlimitedGraphState(state) && unlimitedGraphKeyboardPromptId, state.type !== "none" && !disableInteraction && instructionsId),
|
|
34367
34413
|
ref: graphRef,
|
|
34368
34414
|
tabIndex: 0,
|
|
34369
34415
|
onFocus: event => {
|
|
@@ -41404,51 +41450,9 @@ const init = function init() {
|
|
|
41404
41450
|
replaceDeprecatedWidgets();
|
|
41405
41451
|
};
|
|
41406
41452
|
|
|
41407
|
-
/**
|
|
41408
|
-
* Adds the given perseus library version information to the __perseus_debug__
|
|
41409
|
-
* object and ensures that the object is attached to `globalThis` (`window` in
|
|
41410
|
-
* browser environments).
|
|
41411
|
-
*
|
|
41412
|
-
* This allows each library to provide runtime version information to assist in
|
|
41413
|
-
* debugging in production environments.
|
|
41414
|
-
*/
|
|
41415
|
-
const addLibraryVersionToPerseusDebug = (libraryName, libraryVersion) => {
|
|
41416
|
-
// If the library version is the default value, then we don't want to
|
|
41417
|
-
// prefix it with a "v" to indicate that it is a version number.
|
|
41418
|
-
let prefix = "v";
|
|
41419
|
-
if (libraryVersion === "__lib_version__") {
|
|
41420
|
-
prefix = "";
|
|
41421
|
-
}
|
|
41422
|
-
const formattedVersion = `${prefix}${libraryVersion}`;
|
|
41423
|
-
if (typeof globalThis !== "undefined") {
|
|
41424
|
-
var _globalThis$__perseus;
|
|
41425
|
-
globalThis.__perseus_debug__ = (_globalThis$__perseus = globalThis.__perseus_debug__) != null ? _globalThis$__perseus : {};
|
|
41426
|
-
const existingVersionEntry = globalThis.__perseus_debug__[libraryName];
|
|
41427
|
-
if (existingVersionEntry) {
|
|
41428
|
-
// If we already have an entry and it doesn't match the registered
|
|
41429
|
-
// version, we morph the entry into an array and log a warning.
|
|
41430
|
-
if (existingVersionEntry !== formattedVersion) {
|
|
41431
|
-
// Existing entry might be an array already (oops, at least 2
|
|
41432
|
-
// versions of the library already loaded!).
|
|
41433
|
-
const allVersions = Array.isArray(existingVersionEntry) ? existingVersionEntry : [existingVersionEntry];
|
|
41434
|
-
allVersions.push(formattedVersion);
|
|
41435
|
-
globalThis.__perseus_debug__[libraryName] = allVersions;
|
|
41436
|
-
|
|
41437
|
-
// eslint-disable-next-line no-console
|
|
41438
|
-
console.warn(`Multiple versions of ${libraryName} loaded on this page: ${allVersions.sort().join(", ")}`);
|
|
41439
|
-
}
|
|
41440
|
-
} else {
|
|
41441
|
-
globalThis.__perseus_debug__[libraryName] = formattedVersion;
|
|
41442
|
-
}
|
|
41443
|
-
} else {
|
|
41444
|
-
// eslint-disable-next-line no-console
|
|
41445
|
-
console.warn(`globalThis not found found (${formattedVersion})`);
|
|
41446
|
-
}
|
|
41447
|
-
};
|
|
41448
|
-
|
|
41449
41453
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
41450
41454
|
const libName = "@khanacademy/perseus";
|
|
41451
|
-
const libVersion = "57.2.
|
|
41455
|
+
const libVersion = "57.2.2";
|
|
41452
41456
|
addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
41453
41457
|
|
|
41454
41458
|
const apiVersion = {
|