@khanacademy/perseus 1.0.0 → 1.1.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.
Files changed (49) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/es/index.css +17 -8
  3. package/dist/es/index.js +258 -223
  4. package/dist/es/index.js.map +1 -1
  5. package/dist/index.css +17 -8
  6. package/dist/index.js +261 -225
  7. package/dist/index.js.map +1 -1
  8. package/package.json +1 -1
  9. package/src/components/__stories__/input-with-examples.stories.jsx +1 -0
  10. package/src/components/input-with-examples.jsx +41 -24
  11. package/src/components/number-input.jsx +2 -2
  12. package/src/components/simple-keypad-input.jsx +18 -21
  13. package/src/components/text-input.jsx +5 -3
  14. package/src/index.js +1 -1
  15. package/src/multi-items/__tests__/__snapshots__/multi-renderer_test.js.snap +356 -65
  16. package/src/multi-items/__tests__/multi-renderer_test.js +9 -9
  17. package/src/perseus-types.js +18 -7
  18. package/src/styles/perseus-renderer.less +8 -2
  19. package/src/styles/widgets/matrix.less +2 -0
  20. package/src/styles/widgets/passage.less +9 -5
  21. package/src/util/answer-types.js +2 -3
  22. package/src/util/math.js +3 -10
  23. package/src/widgets/__stories__/numeric-input.stories.jsx +94 -7
  24. package/src/widgets/__tests__/__snapshots__/definition_test.js.snap +4 -4
  25. package/src/widgets/__tests__/__snapshots__/graded-group-set-jipt_test.jsx.snap +15 -6
  26. package/src/widgets/__tests__/__snapshots__/graded-group-set_test.jsx.snap +5 -2
  27. package/src/widgets/__tests__/__snapshots__/graded-group_test.jsx.snap +4 -1
  28. package/src/widgets/__tests__/__snapshots__/group_test.jsx.snap +228 -67
  29. package/src/widgets/__tests__/__snapshots__/matrix_test.jsx.snap +24 -24
  30. package/src/widgets/__tests__/__snapshots__/numeric-input_test.jsx.snap +4 -4
  31. package/src/widgets/__tests__/__snapshots__/radio_test.jsx.snap +2581 -679
  32. package/src/widgets/__tests__/group_test.jsx +4 -4
  33. package/src/widgets/__tests__/numeric-input_test.jsx +12 -8
  34. package/src/widgets/__tests__/passage_test.jsx +81 -0
  35. package/src/widgets/__tests__/radio/base-radio_test.jsx +55 -7
  36. package/src/widgets/__tests__/radio/choice_test.jsx +164 -63
  37. package/src/widgets/__tests__/radio_test.jsx +39 -15
  38. package/src/widgets/definition.jsx +1 -1
  39. package/src/widgets/graded-group.jsx +5 -1
  40. package/src/widgets/group.jsx +84 -102
  41. package/src/widgets/input-number.jsx +6 -1
  42. package/src/widgets/matrix.jsx +17 -1
  43. package/src/widgets/numeric-input.jsx +99 -86
  44. package/src/widgets/radio/base-radio.jsx +3 -1
  45. package/src/widgets/radio/choice-a11y-text.js +62 -0
  46. package/src/widgets/radio/choice-icon/choice-icon.jsx +0 -68
  47. package/src/widgets/radio/choice-icon/library-choice-icon.jsx +5 -10
  48. package/src/widgets/radio/choice-icon/sat-choice-icon.jsx +3 -12
  49. package/src/widgets/radio/choice.jsx +46 -3
@@ -38,15 +38,19 @@
38
38
  line-height: @line-height - 2;
39
39
  }
40
40
  .passage-title div.paragraph {
41
- font-size: @font-size;
41
+ font-family: "Noto Serif", serif;
42
42
  font-weight: 700;
43
+ font-size: 20px;
44
+ line-height: 22px;
45
+
43
46
  margin: 0 0 10px;
44
47
  }
45
48
  .passage-text div.paragraph {
46
- font-size: @font-size;
47
- line-height: @line-height;
48
- margin: 0;
49
- text-indent: 20px;
49
+ font-family: "Noto Serif", serif;
50
+ font-weight: 400;
51
+ font-size: 20px;
52
+ line-height: 24px;
53
+
50
54
  span {
51
55
  text-indent: 0;
52
56
  }
@@ -106,7 +106,7 @@ export const errors = {
106
106
  *
107
107
  */
108
108
 
109
- const KhanAnswerTypes: $FlowFixMe = {
109
+ const KhanAnswerTypes = {
110
110
  /*
111
111
  * predicate answer type
112
112
  *
@@ -653,8 +653,7 @@ const KhanAnswerTypes: $FlowFixMe = {
653
653
  correctAnswer: string,
654
654
  options: $FlowFixMe,
655
655
  ): Predicate {
656
- // TODO(alpert): Don't think this $.trim is necessary
657
- const correctFloat = parseFloat($.trim(correctAnswer));
656
+ const correctFloat = parseFloat(correctAnswer);
658
657
 
659
658
  return [
660
659
  function (guess, maxError) {
package/src/util/math.js CHANGED
@@ -4,14 +4,7 @@ import {number as knumber} from "@khanacademy/kmath";
4
4
  import $ from "jquery";
5
5
  import _ from "underscore";
6
6
 
7
- export type Format =
8
- | "integer"
9
- | "mixed"
10
- | "improper"
11
- | "proper"
12
- | "decimal"
13
- | "percent"
14
- | "pi";
7
+ import type {MathFormat} from "../perseus-types";
15
8
 
16
9
  const KhanMath = {
17
10
  // Simplify formulas before display
@@ -213,7 +206,7 @@ const KhanMath = {
213
206
  // Returns the format (string) of a given numeric string
214
207
  // Note: purposively more inclusive than answer-types' predicate.forms
215
208
  // That is, it is not necessarily true that interpreted input are numeric
216
- getNumericFormat: function (text: string): ?Format {
209
+ getNumericFormat: function (text: string): ?MathFormat {
217
210
  text = $.trim(text);
218
211
  text = text.replace(/\u2212/, "-").replace(/([+-])\s+/g, "$1");
219
212
  if (text.match(/^[+-]?\d+$/)) {
@@ -238,7 +231,7 @@ const KhanMath = {
238
231
  },
239
232
 
240
233
  // Returns a string of the number in a specified format
241
- toNumericString: function (number: number, format?: Format): string {
234
+ toNumericString: function (number: number, format?: MathFormat): string {
242
235
  if (number == null) {
243
236
  return "";
244
237
  }
@@ -1,19 +1,106 @@
1
1
  // @flow
2
+ import {action} from "@storybook/addon-actions";
2
3
  import * as React from "react";
3
4
 
4
5
  import {RendererWithDebugUI} from "../../../../../testing/renderer-with-debug-ui.jsx";
5
6
  import {question1} from "../__testdata__/numeric-input_testdata.js";
7
+ import {NumericInput} from "../numeric-input.jsx";
6
8
 
7
- type StoryArgs = {||};
8
-
9
- type Story = {|
10
- title: string,
9
+ type StoryArgs = {|
10
+ coefficient: boolean,
11
+ currentValue: string,
12
+ rightAlign: boolean,
13
+ size: "normal" | "small",
11
14
  |};
12
15
 
13
- export default ({
16
+ function generateProps(overwrite) {
17
+ const base = {
18
+ alignment: "",
19
+ answers: [],
20
+ containerSizeClass: "medium",
21
+ isLastUsedWidget: true,
22
+ coefficient: false,
23
+ currentValue: "",
24
+ problemNum: 0,
25
+ reviewModeRubric: {
26
+ answers: [],
27
+ labelText: "",
28
+ size: "medium",
29
+ coefficient: false,
30
+ static: false,
31
+ },
32
+ rightAlign: false,
33
+ size: "normal",
34
+ static: false,
35
+ widgetId: "widgetId",
36
+ findWidgets: action("findWidgets"),
37
+ onBlur: action("onBlur"),
38
+ onChange: action("onChange"),
39
+ onFocus: action("onFocus"),
40
+ trackInteraction: action("trackInteraction"),
41
+ };
42
+
43
+ return {...base, ...overwrite};
44
+ }
45
+
46
+ export default {
14
47
  title: "Perseus/Widgets/NumericInput",
15
- }: Story);
48
+ args: {
49
+ coefficient: false,
50
+ currentValue: "8675309",
51
+ rightAlign: false,
52
+ },
53
+ argTypes: {
54
+ size: {
55
+ options: ["normal", "small"],
56
+ control: {type: "radio"},
57
+ defaultValue: "normal",
58
+ },
59
+ },
60
+ };
16
61
 
17
- export const Question1 = (args: StoryArgs): React.Node => {
62
+ export const Question1 = (): React.Node => {
18
63
  return <RendererWithDebugUI question={question1} />;
19
64
  };
65
+
66
+ export const Interactive = (args: StoryArgs): React.Node => {
67
+ const props = generateProps(args);
68
+
69
+ return <NumericInput {...props} />;
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
+ };
@@ -37,13 +37,13 @@ exports[`Definition widget should have a default snapshot: first render 1`] = `
37
37
  >
38
38
  <button
39
39
  aria-disabled="false"
40
- class="button_vr44p2-o_O-shared_lwskrm-o_O-default_1hl5pu8-o_O-small_xwkmkn"
40
+ class="button_vr44p2-o_O-shared_lwskrm-o_O-default_1hl5pu8"
41
41
  role="button"
42
42
  tabindex="0"
43
43
  type="button"
44
44
  >
45
45
  <span
46
- class="text_f1191h-o_O-LabelSmall_hl4zs1-o_O-text_m8a8ki-o_O-textWithFocus_e296pg"
46
+ class="text_f1191h-o_O-LabelLarge_5s82ln-o_O-text_m8a8ki-o_O-textWithFocus_e296pg"
47
47
  >
48
48
  the Pequots
49
49
  </span>
@@ -95,13 +95,13 @@ exports[`Definition widget should have an open state snapshot: open state 1`] =
95
95
  >
96
96
  <button
97
97
  aria-disabled="false"
98
- class="button_vr44p2-o_O-shared_lwskrm-o_O-default_1hl5pu8-o_O-small_xwkmkn"
98
+ class="button_vr44p2-o_O-shared_lwskrm-o_O-default_1hl5pu8"
99
99
  role="button"
100
100
  tabindex="0"
101
101
  type="button"
102
102
  >
103
103
  <span
104
- class="text_f1191h-o_O-LabelSmall_hl4zs1-o_O-text_m8a8ki-o_O-textWithFocus_e296pg-o_O-focus_15mc0l2"
104
+ class="text_f1191h-o_O-LabelLarge_5s82ln-o_O-text_m8a8ki-o_O-textWithFocus_e296pg-o_O-focus_15mc0l2"
105
105
  >
106
106
  the Pequots
107
107
  </span>
@@ -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"
@@ -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"
@@ -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"
@@ -99,7 +99,7 @@ exports[`graded group widget should snapshot 1`] = `
99
99
  autocapitalize="off"
100
100
  autocomplete="off"
101
101
  autocorrect="off"
102
- class="input_1t4b01j-o_O-LabelMedium_1rew30o-o_O-default_1r2dwp3"
102
+ class="input_1t4b01j-o_O-LabelMedium_1rew30o-o_O-default_1r2dwp3-o_O-input_19vw1dn"
103
103
  id="input-with-examples-bnVtZXJpYy1pbnB1dCAx"
104
104
  type="text"
105
105
  value=""
@@ -268,7 +268,10 @@ exports[`graded group widget should snapshot 1`] = `
268
268
  </div>
269
269
  </div>
270
270
  </span>
271
- <p />
271
+ <p
272
+ aria-live="polite"
273
+ role="status"
274
+ />
272
275
  <button
273
276
  aria-disabled="false"
274
277
  class="button_vr44p2-o_O-shared_lwskrm-o_O-default_1w5v67"
@@ -463,7 +463,10 @@ exports[`graded-group should snapshot: initial render (mobile: false) 1`] = `
463
463
  </div>
464
464
  </div>
465
465
  </span>
466
- <p />
466
+ <p
467
+ aria-live="polite"
468
+ role="status"
469
+ />
467
470
  <button
468
471
  aria-disabled="false"
469
472
  class="button_vr44p2-o_O-shared_lwskrm-o_O-default_1w5v67"