@khanacademy/perseus 31.0.1 → 31.1.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/dist/index.css CHANGED
@@ -4440,7 +4440,7 @@ html body .mq-editable-field .mq-selection .mq-nthroot-container * {
4440
4440
  }
4441
4441
 
4442
4442
  .MafsView
4443
- .movable-point:is(:focus-visible, .movable-point--focus)
4443
+ .movable-point:is(:focus, .movable-point--focus)
4444
4444
  .movable-point-focus-outline {
4445
4445
  visibility: visible;
4446
4446
  }
package/dist/index.js CHANGED
@@ -650,6 +650,7 @@ class InnerMathInput extends React__namespace.Component {
650
650
  onFocus: () => this.focus(),
651
651
  onBlur: () => this.blur()
652
652
  }), /*#__PURE__*/React__namespace.createElement(wonderBlocksPopover.Popover, {
653
+ rootBoundary: "document",
653
654
  opened: this.state.keypadOpen,
654
655
  onClose: () => this.closeKeypad(),
655
656
  dismissEnabled: true,
@@ -30541,7 +30542,8 @@ const actions = {
30541
30542
  },
30542
30543
  pointGraph: {
30543
30544
  movePoint,
30544
- addPoint
30545
+ addPoint,
30546
+ removePoint
30545
30547
  },
30546
30548
  polygon: {
30547
30549
  movePoint,
@@ -30577,6 +30579,13 @@ function addPoint(location) {
30577
30579
  location
30578
30580
  };
30579
30581
  }
30582
+ const REMOVE_POINT = "remove-point";
30583
+ function removePoint(index) {
30584
+ return {
30585
+ type: REMOVE_POINT,
30586
+ index
30587
+ };
30588
+ }
30580
30589
  const MOVE_ALL = "move-all";
30581
30590
  function moveAll(delta) {
30582
30591
  return {
@@ -30865,7 +30874,8 @@ const MovablePointView = /*#__PURE__*/React.forwardRef((props, hitboxRef) => {
30865
30874
  color = wonderBlocksTokens.color.blue,
30866
30875
  dragging,
30867
30876
  focusBehavior,
30868
- cursor
30877
+ cursor,
30878
+ onClick = () => {}
30869
30879
  } = props;
30870
30880
 
30871
30881
  // WB Tooltip requires a color name for the background color.
@@ -30903,7 +30913,12 @@ const MovablePointView = /*#__PURE__*/React.forwardRef((props, hitboxRef) => {
30903
30913
  cursor
30904
30914
  },
30905
30915
  "data-testid": "movable-point",
30906
- tabIndex: disableKeyboardInteraction ? -1 : tabIndex(focusBehavior)
30916
+ tabIndex: disableKeyboardInteraction ? -1 : tabIndex(focusBehavior),
30917
+ onFocus: () => {
30918
+ return getOnFocusChangeCallback(focusBehavior)(true);
30919
+ },
30920
+ onBlur: () => getOnFocusChangeCallback(focusBehavior)(false),
30921
+ onClick: onClick
30907
30922
  }, /*#__PURE__*/React__namespace.createElement("circle", {
30908
30923
  className: "movable-point-hitbox",
30909
30924
  r: hitboxSizePx / 2,
@@ -30951,6 +30966,12 @@ function tabIndex(config) {
30951
30966
  }
30952
30967
  return undefined;
30953
30968
  }
30969
+ function getOnFocusChangeCallback(config) {
30970
+ if (config.type === "uncontrolled") {
30971
+ return config.onFocusChange;
30972
+ }
30973
+ return () => {};
30974
+ }
30954
30975
 
30955
30976
  const MovableLine = props => {
30956
30977
  const {
@@ -31548,7 +31569,8 @@ const MovablePoint$1 = props => {
31548
31569
  const elementRef = React.useRef(null);
31549
31570
  const {
31550
31571
  point,
31551
- onMove,
31572
+ onMove = () => {},
31573
+ onFocusChange = () => {},
31552
31574
  cursor,
31553
31575
  color = wonderBlocksTokens.color.blue,
31554
31576
  constrain = p => snap(snapStep, p)
@@ -31568,8 +31590,10 @@ const MovablePoint$1 = props => {
31568
31590
  dragging: dragging,
31569
31591
  focusBehavior: {
31570
31592
  type: "uncontrolled",
31571
- tabIndex: 0
31593
+ tabIndex: 0,
31594
+ onFocusChange
31572
31595
  },
31596
+ onClick: () => elementRef.current?.focus(),
31573
31597
  cursor: cursor
31574
31598
  });
31575
31599
  };
@@ -32801,6 +32825,8 @@ function interactiveGraphReducer(state, action) {
32801
32825
  return doChangeRange(state, action);
32802
32826
  case ADD_POINT:
32803
32827
  return doAddPoint(state, action);
32828
+ case REMOVE_POINT:
32829
+ return doRemovePoint(state, action);
32804
32830
  default:
32805
32831
  throw new wonderStuffCore.UnreachableCaseError(action);
32806
32832
  }
@@ -33164,6 +33190,15 @@ function doAddPoint(state, action) {
33164
33190
  coords: [...state.coords, snappedPoint]
33165
33191
  };
33166
33192
  }
33193
+ function doRemovePoint(state, action) {
33194
+ if (state.type !== "point") {
33195
+ return state;
33196
+ }
33197
+ return {
33198
+ ...state,
33199
+ coords: state.coords.filter((_, i) => i !== action.index)
33200
+ };
33201
+ }
33167
33202
  const getDeltaVertex = (maxMoves, minMoves, delta) => {
33168
33203
  const [deltaX, deltaY] = delta;
33169
33204
  const maxXMove = Math.min(...maxMoves.map(move => move[X]));
@@ -43308,7 +43343,10 @@ var PassageRefTarget$1 = {
43308
43343
  isLintable: true
43309
43344
  };
43310
43345
 
43311
- /* eslint-disable react/forbid-prop-types, react/sort-comp */
43346
+ /**
43347
+ * This is a PhET simulation widget. It is used for rendering simulations
43348
+ * from https://phet.colorado.edu/.
43349
+ */
43312
43350
 
43313
43351
  // For returning user input, but currently the PhET widget
43314
43352
  // does not support accessing user input
@@ -43325,9 +43363,6 @@ class PhetSimulation extends React__namespace.Component {
43325
43363
  super(props);
43326
43364
  this.locale = this.getPhetCompatibleLocale(getDependencies().kaLocale);
43327
43365
  }
43328
- getUserInput() {
43329
- return null;
43330
- }
43331
43366
  async componentDidMount() {
43332
43367
  await this.updateSimState(this.props.url);
43333
43368
  }
@@ -43337,51 +43372,8 @@ class PhetSimulation extends React__namespace.Component {
43337
43372
  await this.updateSimState(this.props.url);
43338
43373
  }
43339
43374
  }
43340
- render() {
43341
- // We sandbox the iframe so that we allowlist only the functionality
43342
- // that we need. This makes it safer to present third-party content
43343
- // from the PhET website.
43344
- // http://www.html5rocks.com/en/tutorials/security/sandboxed-iframes/
43345
- const sandboxProperties = "allow-same-origin allow-scripts";
43346
- return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
43347
- style: styles$6.container
43348
- }, this.state.banner !== null &&
43349
- /*#__PURE__*/
43350
- // TODO(anna): Make this banner focusable
43351
- React__namespace.createElement(wonderBlocksCore.View, {
43352
- style: {
43353
- marginBottom: phoneMargin
43354
- }
43355
- }, /*#__PURE__*/React__namespace.createElement(Banner__default["default"], {
43356
- layout: "floating",
43357
- kind: this.state.banner.kind,
43358
- text: this.state.banner.message
43359
- })), /*#__PURE__*/React__namespace.createElement("iframe", {
43360
- ref: this.iframeRef,
43361
- title: this.props.description,
43362
- sandbox: sandboxProperties,
43363
- style: {
43364
- minWidth: 400,
43365
- height: 360,
43366
- width: "100%",
43367
- borderWidth: 0
43368
- },
43369
- src: this.state.url?.toString(),
43370
- allow: "fullscreen"
43371
- }), /*#__PURE__*/React__namespace.createElement(IconButton__default["default"], {
43372
- icon: cornersOutIcon__default["default"],
43373
- onClick: () => {
43374
- this.iframeRef.current?.requestFullscreen();
43375
- },
43376
- kind: "secondary",
43377
- "aria-label": "Fullscreen",
43378
- style: {
43379
- marginTop: 5,
43380
- marginBottom: 5,
43381
- alignSelf: "flex-end"
43382
- },
43383
- disabled: this.state.url === null
43384
- }));
43375
+ getUserInput() {
43376
+ return null;
43385
43377
  }
43386
43378
  change = (() => {
43387
43379
  var _this = this;
@@ -43481,6 +43473,52 @@ class PhetSimulation extends React__namespace.Component {
43481
43473
  }
43482
43474
  return true;
43483
43475
  }
43476
+ render() {
43477
+ // We sandbox the iframe so that we allowlist only the functionality
43478
+ // that we need. This makes it safer to present third-party content
43479
+ // from the PhET website.
43480
+ // http://www.html5rocks.com/en/tutorials/security/sandboxed-iframes/
43481
+ const sandboxProperties = "allow-same-origin allow-scripts";
43482
+ return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
43483
+ style: styles$6.container
43484
+ }, this.state.banner !== null &&
43485
+ /*#__PURE__*/
43486
+ // TODO(anna): Make this banner focusable
43487
+ React__namespace.createElement(wonderBlocksCore.View, {
43488
+ style: {
43489
+ marginBottom: phoneMargin
43490
+ }
43491
+ }, /*#__PURE__*/React__namespace.createElement(Banner__default["default"], {
43492
+ layout: "floating",
43493
+ kind: this.state.banner.kind,
43494
+ text: this.state.banner.message
43495
+ })), /*#__PURE__*/React__namespace.createElement("iframe", {
43496
+ ref: this.iframeRef,
43497
+ title: this.props.description,
43498
+ sandbox: sandboxProperties,
43499
+ style: {
43500
+ minWidth: 400,
43501
+ height: 360,
43502
+ width: "100%",
43503
+ borderWidth: 0
43504
+ },
43505
+ src: this.state.url?.toString(),
43506
+ allow: "fullscreen"
43507
+ }), /*#__PURE__*/React__namespace.createElement(IconButton__default["default"], {
43508
+ icon: cornersOutIcon__default["default"],
43509
+ onClick: () => {
43510
+ this.iframeRef.current?.requestFullscreen();
43511
+ },
43512
+ kind: "secondary",
43513
+ "aria-label": "Fullscreen",
43514
+ style: {
43515
+ marginTop: 5,
43516
+ marginBottom: 5,
43517
+ alignSelf: "flex-end"
43518
+ },
43519
+ disabled: this.state.url === null
43520
+ }));
43521
+ }
43484
43522
  }
43485
43523
 
43486
43524
  // Setting URL to null will display an error message in the iframe
@@ -43495,14 +43533,6 @@ const makeSafeUrl = (urlString, locale) => {
43495
43533
  url.searchParams.set("locale", locale);
43496
43534
  return url;
43497
43535
  };
43498
- var PhetSimulation$1 = {
43499
- name: "phet-simulation",
43500
- displayName: "PhET Simulation",
43501
- widget: PhetSimulation,
43502
- // Hides widget from content creators until full release
43503
- hidden: true,
43504
- isLintable: true
43505
- };
43506
43536
  const styles$6 = aphrodite.StyleSheet.create({
43507
43537
  container: {
43508
43538
  borderRadius: borderRadiusLarge,
@@ -43513,6 +43543,14 @@ const styles$6 = aphrodite.StyleSheet.create({
43513
43543
  width: 650
43514
43544
  }
43515
43545
  });
43546
+ var PhetSimulation$1 = {
43547
+ name: "phet-simulation",
43548
+ displayName: "PhET Simulation",
43549
+ widget: PhetSimulation,
43550
+ // Hides widget from content creators until full release
43551
+ hidden: true,
43552
+ isLintable: true
43553
+ };
43516
43554
 
43517
43555
  /* eslint-disable react/no-unsafe */
43518
43556
  const {
@@ -45015,7 +45053,7 @@ const init = function (options) {
45015
45053
 
45016
45054
  // This file is processed by a Rollup plugin (replace) to inject the production
45017
45055
  const libName = "@khanacademy/perseus";
45018
- const libVersion = "31.0.1";
45056
+ const libVersion = "31.1.0";
45019
45057
  perseusCore.addLibraryVersionToPerseusDebug(libName, libVersion);
45020
45058
 
45021
45059
  const apiVersion = {