@khanacademy/perseus 1.1.0 → 1.1.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.
Files changed (45) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/es/index.css +3 -0
  3. package/dist/es/index.js +15385 -15345
  4. package/dist/es/index.js.map +1 -1
  5. package/dist/index.css +3 -0
  6. package/dist/index.js +15309 -15269
  7. package/dist/index.js.map +1 -1
  8. package/dist/strings.js +1 -0
  9. package/package.json +1 -1
  10. package/src/__stories__/hints-renderer.stories.jsx +52 -0
  11. package/src/components/__stories__/input-with-examples.stories.jsx +1 -0
  12. package/src/components/input-with-examples.jsx +41 -24
  13. package/src/components/text-input.jsx +5 -3
  14. package/src/hints-renderer.jsx +13 -4
  15. package/src/mixins/__tests__/widget-prop-blacklist_test.js +23 -0
  16. package/src/mixins/widget-prop-blacklist.js +15 -1
  17. package/src/multi-items/__tests__/__snapshots__/multi-renderer_test.js.snap +30 -10
  18. package/src/styles/widgets/matrix.less +2 -0
  19. package/src/styles/widgets/passage.less +1 -0
  20. package/src/types.js +1 -1
  21. package/src/widgets/__stories__/numeric-input.stories.jsx +53 -7
  22. package/src/widgets/__tests__/__snapshots__/graded-group-set-jipt_test.jsx.snap +18 -9
  23. package/src/widgets/__tests__/__snapshots__/graded-group-set_test.jsx.snap +12 -3
  24. package/src/widgets/__tests__/__snapshots__/graded-group_test.jsx.snap +6 -3
  25. package/src/widgets/__tests__/__snapshots__/group_test.jsx.snap +32 -12
  26. package/src/widgets/__tests__/__snapshots__/matrix_test.jsx.snap +24 -24
  27. package/src/widgets/__tests__/__snapshots__/numeric-input_test.jsx.snap +4 -4
  28. package/src/widgets/__tests__/__snapshots__/passage-ref_test.jsx.snap +3 -3
  29. package/src/widgets/__tests__/__snapshots__/passage_test.jsx.snap +6 -6
  30. package/src/widgets/__tests__/__snapshots__/radio_test.jsx.snap +300 -218
  31. package/src/widgets/__tests__/radio/base-radio_test.jsx +90 -6
  32. package/src/widgets/__tests__/radio/choice-icon_test.jsx +74 -0
  33. package/src/widgets/__tests__/radio/choice_test.jsx +39 -30
  34. package/src/widgets/__tests__/radio_test.jsx +228 -22
  35. package/src/widgets/graded-group-set.jsx +8 -1
  36. package/src/widgets/graded-group.jsx +7 -2
  37. package/src/widgets/matrix.jsx +17 -1
  38. package/src/widgets/numeric-input.jsx +12 -6
  39. package/src/widgets/passage-ref.jsx +21 -5
  40. package/src/widgets/passage.jsx +3 -1
  41. package/src/widgets/radio/__stories__/base-radio.stories.jsx +7 -3
  42. package/src/widgets/radio/base-radio.jsx +3 -1
  43. package/src/widgets/radio/choice-icon/cross-out-line.jsx +3 -2
  44. package/src/widgets/radio/choice-icon/library-choice-icon.jsx +17 -6
  45. package/src/widgets/radio/choice.jsx +2 -1
package/dist/strings.js CHANGED
@@ -52,6 +52,7 @@ module.exports = [
52
52
  i18n._("Correct (but you crossed it out)", {}),
53
53
  i18n._("Correct (selected)", {}),
54
54
  i18n._("Correct!", {}),
55
+ i18n._("Current", {}),
55
56
  // I18N: As in the command, "Dilate the polygon"
56
57
  i18n._("Dilate", {}),
57
58
  i18n._("dilation", {}),
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Core Perseus API (includes renderers and widgets)",
4
4
  "author": "Khan Academy",
5
5
  "license": "MIT",
6
- "version": "1.1.0",
6
+ "version": "1.1.2",
7
7
  "publishConfig": {
8
8
  "access": "public"
9
9
  },
@@ -0,0 +1,52 @@
1
+ // @flow
2
+
3
+ import React from "react";
4
+
5
+ import HintsRenderer from "../hints-renderer.jsx";
6
+
7
+ type StoryArgs = {|
8
+ hints: $ReadOnlyArray<$FlowFixMe>,
9
+ hintsVisible: number,
10
+ |};
11
+
12
+ type Story = {|
13
+ title: string,
14
+ argTypes: $FlowFixMe,
15
+ |};
16
+
17
+ export default ({
18
+ title: "Perseus/Renderers/Hints Renderer",
19
+ argTypes: {
20
+ hints: {
21
+ control: "object",
22
+ defaultValue: [
23
+ {
24
+ content: "this is hint 1",
25
+ images: {},
26
+ replace: false,
27
+ widgets: {},
28
+ },
29
+ {
30
+ content: "this is hint 2",
31
+ images: {},
32
+ replace: false,
33
+ widgets: {},
34
+ },
35
+ {
36
+ content: "this is hint 3",
37
+ images: {},
38
+ replace: false,
39
+ widgets: {},
40
+ },
41
+ ],
42
+ },
43
+ hintsVisible: {
44
+ control: {type: "number", min: 0},
45
+ defaultValue: 3,
46
+ },
47
+ },
48
+ }: Story);
49
+
50
+ export const Interactive = (args: StoryArgs): $FlowFixMe => {
51
+ return <HintsRenderer {...args} />;
52
+ };
@@ -17,6 +17,7 @@ const defaultObject = {
17
17
  examples: [],
18
18
  id: "",
19
19
  onChange: () => {},
20
+ value: "",
20
21
  };
21
22
  const testExamples = ["Sample 1", "Sample 2", "Sample 3"];
22
23
 
@@ -1,7 +1,6 @@
1
1
  /* eslint-disable react/sort-comp */
2
2
  // @flow
3
3
  import * as PerseusLinter from "@khanacademy/perseus-linter";
4
- import PropTypes from "prop-types";
5
4
  import * as React from "react";
6
5
  import _ from "underscore";
7
6
 
@@ -14,42 +13,59 @@ import MathOutput from "./math-output.jsx";
14
13
  import TextInput from "./text-input.jsx";
15
14
  import Tooltip from "./tooltip.jsx";
16
15
 
16
+ import type {LinterContextProps} from "../types.js";
17
+
17
18
  const {captureScratchpadTouchStart} = Util;
18
19
  const MATH = "math";
19
20
  const TEXT = "text";
20
21
  const TEX = "tex";
21
22
 
22
- class InputWithExamples extends React.Component<$FlowFixMe, $FlowFixMe> {
23
- static propTypes = {
24
- type: PropTypes.oneOf([MATH, TEXT, TEX]),
25
- value: PropTypes.string,
26
- onChange: PropTypes.func.isRequired,
27
- className: PropTypes.string,
28
- examples: PropTypes.arrayOf(PropTypes.string).isRequired,
29
- shouldShowExamples: PropTypes.bool,
30
- convertDotToTimes: PropTypes.bool,
31
- buttonSet: PropTypes.string,
32
- buttonsVisible: PropTypes.oneOf(["always", "never", "focused"]),
33
- labelText: PropTypes.string,
34
- onFocus: PropTypes.func,
35
- onBlur: PropTypes.func,
36
- disabled: PropTypes.bool,
37
-
38
- // A unique string identifying this InputWithExamples
39
- id: PropTypes.string.isRequired,
40
- linterContext: PerseusLinter.linterContextProps,
41
- };
42
-
43
- static defaultProps: $FlowFixMe = {
23
+ type Props = {|
24
+ type: "math" | "text" | "tex",
25
+ value: string,
26
+ onChange: $FlowFixMe,
27
+ className: string,
28
+ examples: $ReadOnlyArray<string>,
29
+ shouldShowExamples: boolean,
30
+ convertDotToTimes?: boolean,
31
+ buttonSet?: string,
32
+ buttonsVisible?: "always" | "never" | "focused",
33
+ labelText?: string,
34
+ onFocus: () => void,
35
+ onBlur: () => void,
36
+ disabled: boolean,
37
+ style?: $FlowFixMe,
38
+ id: string,
39
+ linterContext: LinterContextProps,
40
+ |};
41
+
42
+ type DefaultProps = {|
43
+ type: Props["type"],
44
+ shouldShowExamples: Props["shouldShowExamples"],
45
+ onFocus: Props["onFocus"],
46
+ onBlur: Props["onBlur"],
47
+ disabled: Props["disabled"],
48
+ linterContext: Props["linterContext"],
49
+ className: Props["className"],
50
+ |};
51
+
52
+ type State = {|
53
+ focused: boolean,
54
+ showExamples: boolean,
55
+ |};
56
+
57
+ class InputWithExamples extends React.Component<Props, State> {
58
+ static defaultProps: DefaultProps = {
44
59
  type: TEXT,
45
60
  shouldShowExamples: true,
46
61
  onFocus: function () {},
47
62
  onBlur: function () {},
48
63
  disabled: false,
49
64
  linterContext: PerseusLinter.linterContextDefault,
65
+ className: "",
50
66
  };
51
67
 
52
- state: $FlowFixMe = {
68
+ state: State = {
53
69
  focused: false,
54
70
  showExamples: false,
55
71
  };
@@ -89,6 +105,7 @@ class InputWithExamples extends React.Component<$FlowFixMe, $FlowFixMe> {
89
105
  onFocus: this._handleFocus,
90
106
  onBlur: this._handleBlur,
91
107
  disabled: this.props.disabled,
108
+ style: this.props.style,
92
109
  };
93
110
 
94
111
  if (this.props.type === TEX) {
@@ -4,6 +4,8 @@ import {TextField} from "@khanacademy/wonder-blocks-form";
4
4
  import * as React from "react";
5
5
  import ReactDOM from "react-dom";
6
6
 
7
+ import type {StyleType} from "@khanacademy/wonder-blocks-core";
8
+
7
9
  type Props = {|
8
10
  value: string | number | null,
9
11
  onChange: (any) => void,
@@ -15,9 +17,7 @@ type Props = {|
15
17
  id?: string,
16
18
  placeholder?: string,
17
19
  onKeyDown?: () => void,
18
-
19
- // TODO: Remove this
20
- style?: $FlowFixMe,
20
+ style?: StyleType,
21
21
  |};
22
22
 
23
23
  type DefaultProps = {|
@@ -57,6 +57,7 @@ class TextInput extends React.Component<Props> {
57
57
  disabled,
58
58
  placeholder,
59
59
  onKeyDown,
60
+ style,
60
61
  } = this.props;
61
62
 
62
63
  const formattedValue = value === null ? "" : value.toString();
@@ -64,6 +65,7 @@ class TextInput extends React.Component<Props> {
64
65
  return (
65
66
  // $FlowIgnore
66
67
  <TextField
68
+ style={style}
67
69
  disabled={disabled}
68
70
  id={this.id}
69
71
  value={formattedValue}
@@ -26,6 +26,8 @@ import type {APIOptionsWithDefaults} from "./types.js";
26
26
  type Props = {|
27
27
  ...React.ElementConfig<Renderer>,
28
28
  className?: string,
29
+ // note (mcurtis): I think this should be $ReadOnlyArray<PerseusRenderer>,
30
+ // but things spiraled out of control when I tried to change it
29
31
  hints: $ReadOnlyArray<$FlowFixMe>,
30
32
  hintsVisible?: number,
31
33
  |};
@@ -72,11 +74,18 @@ class HintsRenderer extends React.Component<Props, State> {
72
74
  this._cacheHintImages();
73
75
  }
74
76
 
77
+ // Force number to make Flow happy
78
+ const prevHintsVisible = prevProps.hintsVisible || 0;
79
+ const nextHintsVisible = this.props.hintsVisible || 0;
80
+
75
81
  // When a new hint is displayed we immediately focus it
76
- // $FlowFixMe[invalid-compare]
77
- if (prevProps.hintsVisible < this.props.hintsVisible) {
78
- // $FlowFixMe[unsafe-addition]
79
- const pos = this.props.hintsVisible - 1;
82
+ // (keeping within the boundaries of hint count)
83
+ if (
84
+ prevHintsVisible < nextHintsVisible &&
85
+ nextHintsVisible <= this.props.hints.length &&
86
+ nextHintsVisible >= 0
87
+ ) {
88
+ const pos = nextHintsVisible - 1;
80
89
  // $FlowFixMe[prop-missing]
81
90
  // $FlowFixMe[incompatible-use]
82
91
  ReactDOM.findDOMNode(this.refs["hintRenderer" + pos]).focus(); // eslint-disable-line react/no-string-refs
@@ -0,0 +1,23 @@
1
+ // @flow
2
+
3
+ import {removeDenylistProps} from "../widget-prop-blacklist.js";
4
+
5
+ describe("removeDenylistProps", () => {
6
+ it("removes props that are in denylist from input", () => {
7
+ // Arrange
8
+ const props = {
9
+ // These props are not on the denylist
10
+ foo: "bar",
11
+ gandalf: "awesome",
12
+ // These props are on the denylist
13
+ key: "f-sharp",
14
+ id: 42,
15
+ };
16
+
17
+ // Act
18
+ const result = removeDenylistProps(props);
19
+
20
+ // Assert
21
+ expect(result).toStrictEqual({foo: "bar", gandalf: "awesome"});
22
+ });
23
+ });
@@ -9,8 +9,10 @@
9
9
  * circular JSON structures sometimes).
10
10
  *
11
11
  * This blacklists things that we know don't need to be serialized.
12
+ *
13
+ * TODO(TB): Go through and update usage of BLACKLIST to DENYLIST: https://khanacademy.atlassian.net/browse/LP-13149?atlOrigin=eyJpIjoiNTI0Y2UwNzQ0MzA4NDYzOGI1YWRmNjEwY2E5YzZlZWUiLCJwIjoiaiJ9
12
14
  */
13
- export default [
15
+ const denylist = [
14
16
  // standard props "added" by react
15
17
  // (technically the renderer still adds them)
16
18
  "key",
@@ -34,3 +36,15 @@ export default [
34
36
  "trackInteraction",
35
37
  "keypadElement",
36
38
  ];
39
+
40
+ export const removeDenylistProps = (props: Object): Object => {
41
+ const newProps = {...props};
42
+ for (const prop of denylist) {
43
+ if (prop in newProps) {
44
+ delete newProps[prop];
45
+ }
46
+ }
47
+ return newProps;
48
+ };
49
+
50
+ export default denylist;
@@ -218,7 +218,7 @@ exports[`multi-item renderer should snapshot: initial render 1`] = `
218
218
  type="button"
219
219
  >
220
220
  <div
221
- style="display: flex; flex-direction: row; justify-content: center; align-content: center; padding-top: 8px; padding-bottom: 8px;"
221
+ style="display: flex; flex-direction: row; justify-content: center; align-content: center; padding-top: 8px; padding-bottom: 8px; padding-left: 8px;"
222
222
  >
223
223
  <div
224
224
  class="iconWrapper_17y0hv9"
@@ -234,7 +234,11 @@ exports[`multi-item renderer should snapshot: initial render 1`] = `
234
234
  data-test-id="choice-icon__library-choice-icon"
235
235
  style="border-color: rgba(33,36,44,0.64); color: rgba(33, 36, 44, 0.64); border-radius: 24px;"
236
236
  >
237
- A
237
+ <div
238
+ class="innerWrapper_177sg8x"
239
+ >
240
+ A
241
+ </div>
238
242
  </div>
239
243
  </span>
240
244
  </div>
@@ -389,7 +393,7 @@ exports[`multi-item renderer should snapshot: initial render 1`] = `
389
393
  type="button"
390
394
  >
391
395
  <div
392
- style="display: flex; flex-direction: row; justify-content: center; align-content: center; padding-top: 8px; padding-bottom: 8px;"
396
+ style="display: flex; flex-direction: row; justify-content: center; align-content: center; padding-top: 8px; padding-bottom: 8px; padding-left: 8px;"
393
397
  >
394
398
  <div
395
399
  class="iconWrapper_17y0hv9"
@@ -405,7 +409,11 @@ exports[`multi-item renderer should snapshot: initial render 1`] = `
405
409
  data-test-id="choice-icon__library-choice-icon"
406
410
  style="border-color: rgba(33,36,44,0.64); color: rgba(33, 36, 44, 0.64); border-radius: 24px;"
407
411
  >
408
- B
412
+ <div
413
+ class="innerWrapper_177sg8x"
414
+ >
415
+ B
416
+ </div>
409
417
  </div>
410
418
  </span>
411
419
  </div>
@@ -560,7 +568,7 @@ exports[`multi-item renderer should snapshot: initial render 1`] = `
560
568
  type="button"
561
569
  >
562
570
  <div
563
- style="display: flex; flex-direction: row; justify-content: center; align-content: center; padding-top: 8px; padding-bottom: 8px;"
571
+ style="display: flex; flex-direction: row; justify-content: center; align-content: center; padding-top: 8px; padding-bottom: 8px; padding-left: 8px;"
564
572
  >
565
573
  <div
566
574
  class="iconWrapper_17y0hv9"
@@ -576,7 +584,11 @@ exports[`multi-item renderer should snapshot: initial render 1`] = `
576
584
  data-test-id="choice-icon__library-choice-icon"
577
585
  style="border-color: rgba(33,36,44,0.64); color: rgba(33, 36, 44, 0.64); border-radius: 24px;"
578
586
  >
579
- C
587
+ <div
588
+ class="innerWrapper_177sg8x"
589
+ >
590
+ C
591
+ </div>
580
592
  </div>
581
593
  </span>
582
594
  </div>
@@ -731,7 +743,7 @@ exports[`multi-item renderer should snapshot: initial render 1`] = `
731
743
  type="button"
732
744
  >
733
745
  <div
734
- style="display: flex; flex-direction: row; justify-content: center; align-content: center; padding-top: 8px; padding-bottom: 8px;"
746
+ style="display: flex; flex-direction: row; justify-content: center; align-content: center; padding-top: 8px; padding-bottom: 8px; padding-left: 8px;"
735
747
  >
736
748
  <div
737
749
  class="iconWrapper_17y0hv9"
@@ -747,7 +759,11 @@ exports[`multi-item renderer should snapshot: initial render 1`] = `
747
759
  data-test-id="choice-icon__library-choice-icon"
748
760
  style="border-color: rgba(33,36,44,0.64); color: rgba(33, 36, 44, 0.64); border-radius: 24px;"
749
761
  >
750
- D
762
+ <div
763
+ class="innerWrapper_177sg8x"
764
+ >
765
+ D
766
+ </div>
751
767
  </div>
752
768
  </span>
753
769
  </div>
@@ -902,7 +918,7 @@ exports[`multi-item renderer should snapshot: initial render 1`] = `
902
918
  type="button"
903
919
  >
904
920
  <div
905
- style="display: flex; flex-direction: row; justify-content: center; align-content: center; padding-top: 8px; padding-bottom: 8px;"
921
+ style="display: flex; flex-direction: row; justify-content: center; align-content: center; padding-top: 8px; padding-bottom: 8px; padding-left: 8px;"
906
922
  >
907
923
  <div
908
924
  class="iconWrapper_17y0hv9"
@@ -918,7 +934,11 @@ exports[`multi-item renderer should snapshot: initial render 1`] = `
918
934
  data-test-id="choice-icon__library-choice-icon"
919
935
  style="border-color: rgba(33,36,44,0.64); color: rgba(33, 36, 44, 0.64); border-radius: 24px;"
920
936
  >
921
- E
937
+ <div
938
+ class="innerWrapper_177sg8x"
939
+ >
940
+ E
941
+ </div>
922
942
  </div>
923
943
  </span>
924
944
  </div>
@@ -43,11 +43,13 @@
43
43
  &.bracket-left {
44
44
  border-color: @bracketColor;
45
45
  border-left-width: @borderWidth;
46
+ border-right-width: 0;
46
47
  left: 3px;
47
48
  }
48
49
 
49
50
  &.bracket-right {
50
51
  border-color: @bracketColor;
52
+ border-left-width: 0;
51
53
  border-right-width: @borderWidth;
52
54
  margin-left: (1px - 2 * @borderWidth);
53
55
  }
@@ -50,6 +50,7 @@
50
50
  font-weight: 400;
51
51
  font-size: 20px;
52
52
  line-height: 24px;
53
+ text-indent: 20px;
53
54
 
54
55
  span {
55
56
  text-indent: 0;
package/src/types.js CHANGED
@@ -491,7 +491,7 @@ export type WidgetProps<RenderProps, Rubric> = {|
491
491
  questionCompleted?: boolean,
492
492
  onFocus: (blurPath: FocusPath) => void,
493
493
  onBlur: (blurPath: FocusPath) => void,
494
- findWidgets: (FilterCriterion) => any,
494
+ findWidgets: (FilterCriterion) => $ReadOnlyArray<Widget>,
495
495
  reviewModeRubric: Rubric,
496
496
  onChange: ChangeHandler,
497
497
  trackInteraction: (extraData?: any) => void,
@@ -7,12 +7,10 @@ import {question1} from "../__testdata__/numeric-input_testdata.js";
7
7
  import {NumericInput} from "../numeric-input.jsx";
8
8
 
9
9
  type StoryArgs = {|
10
+ coefficient: boolean,
10
11
  currentValue: string,
11
- |};
12
-
13
- type Story = {|
14
- title: string,
15
- args: StoryArgs,
12
+ rightAlign: boolean,
13
+ size: "normal" | "small",
16
14
  |};
17
15
 
18
16
  function generateProps(overwrite) {
@@ -21,6 +19,7 @@ function generateProps(overwrite) {
21
19
  answers: [],
22
20
  containerSizeClass: "medium",
23
21
  isLastUsedWidget: true,
22
+ coefficient: false,
24
23
  currentValue: "",
25
24
  problemNum: 0,
26
25
  reviewModeRubric: {
@@ -30,6 +29,8 @@ function generateProps(overwrite) {
30
29
  coefficient: false,
31
30
  static: false,
32
31
  },
32
+ rightAlign: false,
33
+ size: "normal",
33
34
  static: false,
34
35
  widgetId: "widgetId",
35
36
  findWidgets: action("findWidgets"),
@@ -42,12 +43,21 @@ function generateProps(overwrite) {
42
43
  return {...base, ...overwrite};
43
44
  }
44
45
 
45
- export default ({
46
+ export default {
46
47
  title: "Perseus/Widgets/NumericInput",
47
48
  args: {
49
+ coefficient: false,
48
50
  currentValue: "8675309",
51
+ rightAlign: false,
52
+ },
53
+ argTypes: {
54
+ size: {
55
+ options: ["normal", "small"],
56
+ control: {type: "radio"},
57
+ defaultValue: "normal",
58
+ },
49
59
  },
50
- }: Story);
60
+ };
51
61
 
52
62
  export const Question1 = (): React.Node => {
53
63
  return <RendererWithDebugUI question={question1} />;
@@ -58,3 +68,39 @@ export const Interactive = (args: StoryArgs): React.Node => {
58
68
 
59
69
  return <NumericInput {...props} />;
60
70
  };
71
+
72
+ export const Sizes = (args: StoryArgs): React.Node => {
73
+ const smallProps = generateProps({...args, size: "small"});
74
+ const normalProps = generateProps({...args, size: "normal"});
75
+
76
+ return (
77
+ <div>
78
+ <label>
79
+ Small:
80
+ <NumericInput {...smallProps} />
81
+ </label>
82
+ <label>
83
+ Normal:
84
+ <NumericInput {...normalProps} />
85
+ </label>
86
+ </div>
87
+ );
88
+ };
89
+
90
+ export const TextAlignment = (args: StoryArgs): React.Node => {
91
+ const leftProps = generateProps({...args, rightAlign: false});
92
+ const rightProps = generateProps({...args, rightAlign: true});
93
+
94
+ return (
95
+ <div>
96
+ <label>
97
+ Left:
98
+ <NumericInput {...leftProps} />
99
+ </label>
100
+ <label>
101
+ Right:
102
+ <NumericInput {...rightProps} />
103
+ </label>
104
+ </div>
105
+ );
106
+ };
@@ -33,7 +33,7 @@ exports[`graded-group-set should render all graded groups 1`] = `
33
33
  class="perseus-graded-group"
34
34
  >
35
35
  <div
36
- class="title_6pk9ag"
36
+ class="title_1lagzkb"
37
37
  >
38
38
  Problem 1a
39
39
  </div>
@@ -73,7 +73,7 @@ exports[`graded-group-set should render all graded groups 1`] = `
73
73
  autocapitalize="off"
74
74
  autocomplete="off"
75
75
  autocorrect="off"
76
- class="input_1t4b01j-o_O-LabelMedium_1rew30o-o_O-default_1r2dwp3"
76
+ class="input_1t4b01j-o_O-LabelMedium_1rew30o-o_O-default_1r2dwp3-o_O-input_19vw1dn"
77
77
  id="input-with-examples-bnVtZXJpYy1pbnB1dCAx"
78
78
  type="text"
79
79
  value=""
@@ -242,7 +242,10 @@ exports[`graded-group-set should render all graded groups 1`] = `
242
242
  </div>
243
243
  </div>
244
244
  </span>
245
- <p />
245
+ <p
246
+ aria-live="polite"
247
+ role="status"
248
+ />
246
249
  <button
247
250
  aria-disabled="false"
248
251
  class="button_vr44p2-o_O-shared_lwskrm-o_O-default_1w5v67"
@@ -267,7 +270,7 @@ exports[`graded-group-set should render all graded groups 1`] = `
267
270
  class="perseus-graded-group"
268
271
  >
269
272
  <div
270
- class="title_6pk9ag"
273
+ class="title_1lagzkb"
271
274
  >
272
275
  Problem 1b
273
276
  </div>
@@ -307,7 +310,7 @@ exports[`graded-group-set should render all graded groups 1`] = `
307
310
  autocapitalize="off"
308
311
  autocomplete="off"
309
312
  autocorrect="off"
310
- class="input_1t4b01j-o_O-LabelMedium_1rew30o-o_O-default_1r2dwp3"
313
+ class="input_1t4b01j-o_O-LabelMedium_1rew30o-o_O-default_1r2dwp3-o_O-input_19vw1dn"
311
314
  id="input-with-examples-bnVtZXJpYy1pbnB1dCAx"
312
315
  type="text"
313
316
  value=""
@@ -476,7 +479,10 @@ exports[`graded-group-set should render all graded groups 1`] = `
476
479
  </div>
477
480
  </div>
478
481
  </span>
479
- <p />
482
+ <p
483
+ aria-live="polite"
484
+ role="status"
485
+ />
480
486
  <button
481
487
  aria-disabled="false"
482
488
  class="button_vr44p2-o_O-shared_lwskrm-o_O-default_1w5v67"
@@ -501,7 +507,7 @@ exports[`graded-group-set should render all graded groups 1`] = `
501
507
  class="perseus-graded-group"
502
508
  >
503
509
  <div
504
- class="title_6pk9ag"
510
+ class="title_1lagzkb"
505
511
  >
506
512
  Problem 1c
507
513
  </div>
@@ -541,7 +547,7 @@ exports[`graded-group-set should render all graded groups 1`] = `
541
547
  autocapitalize="off"
542
548
  autocomplete="off"
543
549
  autocorrect="off"
544
- class="input_1t4b01j-o_O-LabelMedium_1rew30o-o_O-default_1r2dwp3"
550
+ class="input_1t4b01j-o_O-LabelMedium_1rew30o-o_O-default_1r2dwp3-o_O-input_19vw1dn"
545
551
  id="input-with-examples-bnVtZXJpYy1pbnB1dCAx"
546
552
  type="text"
547
553
  value=""
@@ -710,7 +716,10 @@ exports[`graded-group-set should render all graded groups 1`] = `
710
716
  </div>
711
717
  </div>
712
718
  </span>
713
- <p />
719
+ <p
720
+ aria-live="polite"
721
+ role="status"
722
+ />
714
723
  <button
715
724
  aria-disabled="false"
716
725
  class="button_vr44p2-o_O-shared_lwskrm-o_O-default_1w5v67"
@@ -47,7 +47,13 @@ exports[`graded group widget should snapshot 1`] = `
47
47
  aria-label="Skip to Problem 1a"
48
48
  class="indicator_1ezvcme-o_O-selectedIndicator_1v68a6x"
49
49
  role="button"
50
- />
50
+ >
51
+ <span
52
+ class="srOnly_19bpjuy"
53
+ >
54
+ Current
55
+ </span>
56
+ </div>
51
57
  <div
52
58
  aria-label="Skip to Problem 1b"
53
59
  class="indicator_1ezvcme"
@@ -99,7 +105,7 @@ exports[`graded group widget should snapshot 1`] = `
99
105
  autocapitalize="off"
100
106
  autocomplete="off"
101
107
  autocorrect="off"
102
- class="input_1t4b01j-o_O-LabelMedium_1rew30o-o_O-default_1r2dwp3"
108
+ class="input_1t4b01j-o_O-LabelMedium_1rew30o-o_O-default_1r2dwp3-o_O-input_19vw1dn"
103
109
  id="input-with-examples-bnVtZXJpYy1pbnB1dCAx"
104
110
  type="text"
105
111
  value=""
@@ -268,7 +274,10 @@ exports[`graded group widget should snapshot 1`] = `
268
274
  </div>
269
275
  </div>
270
276
  </span>
271
- <p />
277
+ <p
278
+ aria-live="polite"
279
+ role="status"
280
+ />
272
281
  <button
273
282
  aria-disabled="false"
274
283
  class="button_vr44p2-o_O-shared_lwskrm-o_O-default_1w5v67"