@khanacademy/perseus 0.3.4 → 0.4.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.
Files changed (50) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/es/index.js +8232 -5591
  3. package/dist/es/index.js.map +1 -1
  4. package/dist/index.js +17876 -15237
  5. package/dist/index.js.map +1 -1
  6. package/dist/strings.js +0 -1
  7. package/package.json +9 -8
  8. package/src/__tests__/__snapshots__/item-renderer_test.jsx.snap +2 -3
  9. package/src/__tests__/__snapshots__/server-item-renderer_test.jsx.snap +2 -3
  10. package/src/__tests__/renderer-api_test.jsx +3 -27
  11. package/src/components/__stories__/svg-image.stories.jsx +11 -0
  12. package/src/components/fixed-to-responsive.jsx +1 -0
  13. package/src/components/input-with-examples.jsx +3 -1
  14. package/src/components/svg-image.jsx +10 -7
  15. package/src/components/text-input.jsx +65 -16
  16. package/src/definition-context.js +59 -0
  17. package/src/index.js +5 -1
  18. package/src/multi-items/__tests__/__snapshots__/multi-renderer_test.js.snap +438 -523
  19. package/src/multi-items/__tests__/multi-renderer_test.js +9 -9
  20. package/src/renderer.jsx +13 -6
  21. package/src/types.js +3 -4
  22. package/src/widgets/__stories__/definition.stories.jsx +44 -0
  23. package/src/widgets/__tests__/__snapshots__/categorizer_test.jsx.snap +76 -8
  24. package/src/widgets/__tests__/__snapshots__/graded-group-set-jipt_test.jsx.snap +6 -9
  25. package/src/widgets/__tests__/__snapshots__/graded-group-set_test.jsx.snap +2 -3
  26. package/src/widgets/__tests__/__snapshots__/grapher_test.jsx.snap +19 -2
  27. package/src/widgets/__tests__/__snapshots__/group_test.jsx.snap +338 -390
  28. package/src/widgets/__tests__/__snapshots__/image_test.jsx.snap +38 -4
  29. package/src/widgets/__tests__/__snapshots__/interactive-graph_test.jsx.snap +114 -12
  30. package/src/widgets/__tests__/__snapshots__/matrix_test.jsx.snap +120 -48
  31. package/src/widgets/__tests__/__snapshots__/numeric-input_test.jsx.snap +8 -12
  32. package/src/widgets/__tests__/__snapshots__/radio_test.jsx.snap +3615 -4517
  33. package/src/widgets/__tests__/graded-group-set-jipt_test.jsx +0 -1
  34. package/src/widgets/__tests__/grapher.cypress.jsx +236 -176
  35. package/src/widgets/__tests__/group_test.jsx +4 -4
  36. package/src/widgets/__tests__/interactive-graph.cypress.jsx +371 -291
  37. package/src/widgets/__tests__/radio_test.jsx +73 -114
  38. package/src/widgets/definition.jsx +34 -29
  39. package/src/widgets/numeric-input.jsx +2 -15
  40. package/src/widgets/radio/base-radio.jsx +1 -1
  41. package/src/widgets/radio/choice-icon.jsx +11 -10
  42. package/src/widgets/radio/choice.jsx +164 -396
  43. package/src/widgets/radio/cross-out-button.jsx +3 -5
  44. package/src/widgets/radio/option-status.jsx +4 -5
  45. package/src/widgets/radio/__stories__/cross-out-menu.stories.jsx +0 -59
  46. package/src/widgets/radio/__stories__/cross-out-tooltip.stories.jsx +0 -59
  47. package/src/widgets/radio/__stories__/toggleable-radio-button.stories.jsx +0 -28
  48. package/src/widgets/radio/cross-out-menu-wrapper.jsx +0 -492
  49. package/src/widgets/radio/cross-out-tooltip.jsx +0 -129
  50. package/src/widgets/radio/toggleable-radio-button.jsx +0 -133
@@ -136,7 +136,7 @@ describe("multi-item renderer", () => {
136
136
  // selected, a value is entered). You can see the result of this in the `choiceStates`
137
137
  // array in the captured state below where the choice at index 2 has
138
138
  // `"selected": true` (instead of false) and the input-number has a `currentValue`.
139
- userEvent.click(screen.getAllByRole("radio")[2]); // Correct
139
+ userEvent.click(screen.getAllByRole("checkbox")[2]); // Correct
140
140
  userEvent.paste(screen.getByRole("textbox"), "+42"); // Correct
141
141
 
142
142
  // Act
@@ -268,7 +268,7 @@ describe("multi-item renderer", () => {
268
268
  // Arrange
269
269
  const {renderer} = renderSimpleQuestion(question1);
270
270
 
271
- userEvent.click(screen.getAllByRole("radio")[2]);
271
+ userEvent.click(screen.getAllByRole("checkbox")[2]);
272
272
  userEvent.paste(screen.getByRole("textbox"), "99");
273
273
 
274
274
  // Act
@@ -525,11 +525,11 @@ describe("multi-item renderer", () => {
525
525
  renderer.restoreSerializedState(state);
526
526
 
527
527
  // Assert
528
- expect(screen.getAllByRole("radio")[0]).not.toBeChecked();
529
- expect(screen.getAllByRole("radio")[1]).not.toBeChecked();
530
- expect(screen.getAllByRole("radio")[2]).toBeChecked();
531
- expect(screen.getAllByRole("radio")[3]).not.toBeChecked();
532
- expect(screen.getAllByRole("radio")[4]).not.toBeChecked();
528
+ expect(screen.getAllByRole("checkbox")[0]).not.toBeChecked();
529
+ expect(screen.getAllByRole("checkbox")[1]).not.toBeChecked();
530
+ expect(screen.getAllByRole("checkbox")[2]).toBeChecked();
531
+ expect(screen.getAllByRole("checkbox")[3]).not.toBeChecked();
532
+ expect(screen.getAllByRole("checkbox")[4]).not.toBeChecked();
533
533
  expect(screen.getByRole("textbox")).toHaveValue("+42");
534
534
  });
535
535
 
@@ -586,7 +586,7 @@ describe("multi-item renderer", () => {
586
586
  // Arrange
587
587
  const {renderer} = renderSimpleQuestion(question1);
588
588
 
589
- userEvent.click(screen.getAllByRole("radio")[3]); // Correct
589
+ userEvent.click(screen.getAllByRole("checkbox")[3]); // Correct
590
590
  userEvent.paste(screen.getByRole("textbox"), "-42"); // Correct
591
591
 
592
592
  // Act
@@ -747,7 +747,7 @@ describe("multi-item renderer", () => {
747
747
  // Arrange
748
748
  const {renderer} = renderSimpleQuestion(question1);
749
749
 
750
- userEvent.click(screen.getAllByRole("radio")[3]); // Correct
750
+ userEvent.click(screen.getAllByRole("checkbox")[3]); // Correct
751
751
  userEvent.paste(screen.getByRole("textbox"), "-42"); // Correct
752
752
 
753
753
  // Act
package/src/renderer.jsx CHANGED
@@ -12,6 +12,7 @@ import SvgImage from "./components/svg-image.jsx";
12
12
  import TeX from "./components/tex.jsx";
13
13
  import ZoomableTeX from "./components/zoomable-tex.jsx";
14
14
  import Zoomable from "./components/zoomable.jsx";
15
+ import {DefinitionProvider} from "./definition-context.js";
15
16
  import {getDependencies} from "./dependencies.js";
16
17
  import ErrorBoundary from "./error-boundary.jsx";
17
18
  import InteractionTracker from "./interaction-tracker.js";
@@ -1843,11 +1844,15 @@ class Renderer extends React.Component<Props, State> {
1843
1844
  // this attribute and render the text with markdown.
1844
1845
  return (
1845
1846
  <KatexProvider>
1846
- <div
1847
- data-perseus-component-index={this.translationIndex}
1848
- >
1849
- {content}
1850
- </div>
1847
+ <DefinitionProvider>
1848
+ <div
1849
+ data-perseus-component-index={
1850
+ this.translationIndex
1851
+ }
1852
+ >
1853
+ {content}
1854
+ </div>
1855
+ </DefinitionProvider>
1851
1856
  </KatexProvider>
1852
1857
  );
1853
1858
  }
@@ -1907,7 +1912,9 @@ class Renderer extends React.Component<Props, State> {
1907
1912
 
1908
1913
  this.lastRenderedMarkdown = (
1909
1914
  <KatexProvider>
1910
- <div className={className}>{markdownContents}</div>
1915
+ <DefinitionProvider>
1916
+ <div className={className}>{markdownContents}</div>
1917
+ </DefinitionProvider>
1911
1918
  </KatexProvider>
1912
1919
  );
1913
1920
  return this.lastRenderedMarkdown;
package/src/types.js CHANGED
@@ -262,6 +262,9 @@ export type APIOptions = $ReadOnly<{|
262
262
  // callsites should have been switched to using the "final"
263
263
  // designs.
264
264
  radioStyleVersion?: "intermediate" | "final",
265
+
266
+ // TODO(Nicole): Remove this after landing wonderblock-ifying
267
+ // the radio widget
265
268
  primaryProductColor?: string,
266
269
  |},
267
270
 
@@ -316,8 +319,6 @@ export type DomInsertCheckFn = (
316
319
 
317
320
  export type JIPT = {|
318
321
  useJIPT: boolean,
319
- // eslint-disable-next-line ft-flow/no-mutable-array
320
- domInsertChecks: Array<DomInsertCheckFn>,
321
322
  |};
322
323
 
323
324
  export type JiptLabelStore = {|
@@ -404,9 +405,7 @@ export type PerseusDependencies = {|
404
405
  // RequestInfo
405
406
  isDevServer: boolean,
406
407
  kaLocale: string,
407
- isPhone: boolean,
408
408
  isMobile: boolean,
409
- isTablet: boolean,
410
409
  |};
411
410
 
412
411
  export type APIOptionsWithDefaults = $ReadOnly<{|
@@ -31,8 +31,52 @@ const question1 = {
31
31
  },
32
32
  };
33
33
 
34
+ const question2 = {
35
+ content:
36
+ "Read the excerpt and answer the question below. \n\nThe [[\u2603 definition 2]] and Council of the Massachusetts had much conference many days; and at last . . . . concluded a peace and friendship with [[\u2603 definition 1]], upon these conditions.",
37
+ images: {},
38
+ widgets: {
39
+ "definition 1": {
40
+ graded: true,
41
+ version: {
42
+ major: 0,
43
+ minor: 0,
44
+ },
45
+ static: false,
46
+ type: "definition",
47
+ options: {
48
+ definition:
49
+ "A Native American people in Connecticut; white settlers in New England, the Pequots, and their respective allies were at war from 1636-1638.",
50
+ togglePrompt: "the Pequots",
51
+ static: false,
52
+ },
53
+ alignment: "default",
54
+ },
55
+ "definition 2": {
56
+ graded: true,
57
+ version: {
58
+ major: 0,
59
+ minor: 0,
60
+ },
61
+ static: false,
62
+ type: "definition",
63
+ options: {
64
+ definition:
65
+ "A governor is an administrative leader and head of a polity or political region, ranking under the head of state and in some cases, such as governors-general, as the head of state's official representative.",
66
+ togglePrompt: "Governor",
67
+ static: false,
68
+ },
69
+ alignment: "default",
70
+ },
71
+ },
72
+ };
73
+
34
74
  type StoryArgs = {||};
35
75
 
36
76
  export const Question1 = (args: StoryArgs): React.Node => {
37
77
  return <RendererWithDebugUI question={question1} />;
38
78
  };
79
+
80
+ export const MultipleDefintions = (args: StoryArgs): React.Node => {
81
+ return <RendererWithDebugUI question={question2} />;
82
+ };
@@ -375,8 +375,25 @@ exports[`categorizer widget should snapshot on mobile: first mobile render 1`] =
375
375
  style="padding-bottom: 101.36%;"
376
376
  />
377
377
  <span
378
- style="background: url(/images/spinner.gif) no-repeat; background-position: center; width: 100%; height: 100%; position: absolute; min-width: 20px;"
379
- />
378
+ style="top: 0px; left: 0px; width: 100%; height: 100%; position: absolute; min-width: 20px; display: flex; justify-content: center; align-content: center;"
379
+ >
380
+ <div
381
+ class="default_xu2jcg-o_O-spinnerContainer_agrn11"
382
+ >
383
+ <svg
384
+ height="48"
385
+ viewBox="0 0 48 48"
386
+ width="48"
387
+ xmlns="http://www.w3.org/2000/svg"
388
+ >
389
+ <path
390
+ class="loadingSpinner_1dvgeb3-o_O-inlineStyles_1kzk0y9"
391
+ d="M44.19 23.455a1.91 1.91 0 1 1 3.801 0h.003c.004.18.006.363.006.545 0 13.255-10.745 24-24 24S0 37.255 0 24 10.745 0 24 0c.182 0 .364.002.545.006V.01a1.91 1.91 0 1 1 0 3.801v.015A20.564 20.564 0 0 0 24 3.818C12.854 3.818 3.818 12.854 3.818 24c0 11.146 9.036 20.182 20.182 20.182 11.146 0 20.182-9.036 20.182-20.182 0-.182-.003-.364-.007-.545h.015z"
392
+ fill-rule="nonzero"
393
+ />
394
+ </svg>
395
+ </div>
396
+ </span>
380
397
  </div>
381
398
  </div>
382
399
  </div>
@@ -407,8 +424,25 @@ exports[`categorizer widget should snapshot on mobile: first mobile render 1`] =
407
424
  style="padding-bottom: 91.39%;"
408
425
  />
409
426
  <span
410
- style="background: url(/images/spinner.gif) no-repeat; background-position: center; width: 100%; height: 100%; position: absolute; min-width: 20px;"
411
- />
427
+ style="top: 0px; left: 0px; width: 100%; height: 100%; position: absolute; min-width: 20px; display: flex; justify-content: center; align-content: center;"
428
+ >
429
+ <div
430
+ class="default_xu2jcg-o_O-spinnerContainer_agrn11"
431
+ >
432
+ <svg
433
+ height="48"
434
+ viewBox="0 0 48 48"
435
+ width="48"
436
+ xmlns="http://www.w3.org/2000/svg"
437
+ >
438
+ <path
439
+ class="loadingSpinner_1dvgeb3-o_O-inlineStyles_1kzk0y9"
440
+ d="M44.19 23.455a1.91 1.91 0 1 1 3.801 0h.003c.004.18.006.363.006.545 0 13.255-10.745 24-24 24S0 37.255 0 24 10.745 0 24 0c.182 0 .364.002.545.006V.01a1.91 1.91 0 1 1 0 3.801v.015A20.564 20.564 0 0 0 24 3.818C12.854 3.818 3.818 12.854 3.818 24c0 11.146 9.036 20.182 20.182 20.182 11.146 0 20.182-9.036 20.182-20.182 0-.182-.003-.364-.007-.545h.015z"
441
+ fill-rule="nonzero"
442
+ />
443
+ </svg>
444
+ </div>
445
+ </span>
412
446
  </div>
413
447
 
414
448
  </div>
@@ -884,8 +918,25 @@ exports[`categorizer widget should snapshot: first render 1`] = `
884
918
  style="padding-bottom: 101.36%;"
885
919
  />
886
920
  <span
887
- style="background: url(/images/spinner.gif) no-repeat; background-position: center; width: 100%; height: 100%; position: absolute; min-width: 20px;"
888
- />
921
+ style="top: 0px; left: 0px; width: 100%; height: 100%; position: absolute; min-width: 20px; display: flex; justify-content: center; align-content: center;"
922
+ >
923
+ <div
924
+ class="default_xu2jcg-o_O-spinnerContainer_agrn11"
925
+ >
926
+ <svg
927
+ height="48"
928
+ viewBox="0 0 48 48"
929
+ width="48"
930
+ xmlns="http://www.w3.org/2000/svg"
931
+ >
932
+ <path
933
+ class="loadingSpinner_1dvgeb3-o_O-inlineStyles_1kzk0y9"
934
+ d="M44.19 23.455a1.91 1.91 0 1 1 3.801 0h.003c.004.18.006.363.006.545 0 13.255-10.745 24-24 24S0 37.255 0 24 10.745 0 24 0c.182 0 .364.002.545.006V.01a1.91 1.91 0 1 1 0 3.801v.015A20.564 20.564 0 0 0 24 3.818C12.854 3.818 3.818 12.854 3.818 24c0 11.146 9.036 20.182 20.182 20.182 11.146 0 20.182-9.036 20.182-20.182 0-.182-.003-.364-.007-.545h.015z"
935
+ fill-rule="nonzero"
936
+ />
937
+ </svg>
938
+ </div>
939
+ </span>
889
940
  </div>
890
941
  </div>
891
942
  </div>
@@ -916,8 +967,25 @@ exports[`categorizer widget should snapshot: first render 1`] = `
916
967
  style="padding-bottom: 91.39%;"
917
968
  />
918
969
  <span
919
- style="background: url(/images/spinner.gif) no-repeat; background-position: center; width: 100%; height: 100%; position: absolute; min-width: 20px;"
920
- />
970
+ style="top: 0px; left: 0px; width: 100%; height: 100%; position: absolute; min-width: 20px; display: flex; justify-content: center; align-content: center;"
971
+ >
972
+ <div
973
+ class="default_xu2jcg-o_O-spinnerContainer_agrn11"
974
+ >
975
+ <svg
976
+ height="48"
977
+ viewBox="0 0 48 48"
978
+ width="48"
979
+ xmlns="http://www.w3.org/2000/svg"
980
+ >
981
+ <path
982
+ class="loadingSpinner_1dvgeb3-o_O-inlineStyles_1kzk0y9"
983
+ d="M44.19 23.455a1.91 1.91 0 1 1 3.801 0h.003c.004.18.006.363.006.545 0 13.255-10.745 24-24 24S0 37.255 0 24 10.745 0 24 0c.182 0 .364.002.545.006V.01a1.91 1.91 0 1 1 0 3.801v.015A20.564 20.564 0 0 0 24 3.818C12.854 3.818 3.818 12.854 3.818 24c0 11.146 9.036 20.182 20.182 20.182 11.146 0 20.182-9.036 20.182-20.182 0-.182-.003-.364-.007-.545h.015z"
984
+ fill-rule="nonzero"
985
+ />
986
+ </svg>
987
+ </div>
988
+ </span>
921
989
  </div>
922
990
 
923
991
  </div>
@@ -69,13 +69,12 @@ exports[`graded-group-set should render all graded groups 1`] = `
69
69
  <span>
70
70
  <div>
71
71
  <input
72
- aria-describedby="input-with-examples-bnVtZXJpYy1pbnB1dCAx"
73
72
  aria-label="Your answer:"
74
73
  autocapitalize="off"
75
74
  autocomplete="off"
76
75
  autocorrect="off"
77
- class="perseus-input perseus-interactive perseus-input-size-normal"
78
- spellcheck="false"
76
+ class="input_1t4b01j-o_O-LabelMedium_1rew30o-o_O-default_1r2dwp3"
77
+ id="input-with-examples-bnVtZXJpYy1pbnB1dCAx"
79
78
  type="text"
80
79
  value=""
81
80
  />
@@ -304,13 +303,12 @@ exports[`graded-group-set should render all graded groups 1`] = `
304
303
  <span>
305
304
  <div>
306
305
  <input
307
- aria-describedby="input-with-examples-bnVtZXJpYy1pbnB1dCAx"
308
306
  aria-label="Your answer:"
309
307
  autocapitalize="off"
310
308
  autocomplete="off"
311
309
  autocorrect="off"
312
- class="perseus-input perseus-interactive perseus-input-size-normal"
313
- spellcheck="false"
310
+ class="input_1t4b01j-o_O-LabelMedium_1rew30o-o_O-default_1r2dwp3"
311
+ id="input-with-examples-bnVtZXJpYy1pbnB1dCAx"
314
312
  type="text"
315
313
  value=""
316
314
  />
@@ -539,13 +537,12 @@ exports[`graded-group-set should render all graded groups 1`] = `
539
537
  <span>
540
538
  <div>
541
539
  <input
542
- aria-describedby="input-with-examples-bnVtZXJpYy1pbnB1dCAx"
543
540
  aria-label="Your answer:"
544
541
  autocapitalize="off"
545
542
  autocomplete="off"
546
543
  autocorrect="off"
547
- class="perseus-input perseus-interactive perseus-input-size-normal"
548
- spellcheck="false"
544
+ class="input_1t4b01j-o_O-LabelMedium_1rew30o-o_O-default_1r2dwp3"
545
+ id="input-with-examples-bnVtZXJpYy1pbnB1dCAx"
549
546
  type="text"
550
547
  value=""
551
548
  />
@@ -95,13 +95,12 @@ exports[`graded group widget should snapshot 1`] = `
95
95
  <span>
96
96
  <div>
97
97
  <input
98
- aria-describedby="input-with-examples-bnVtZXJpYy1pbnB1dCAx"
99
98
  aria-label="Your answer:"
100
99
  autocapitalize="off"
101
100
  autocomplete="off"
102
101
  autocorrect="off"
103
- class="perseus-input perseus-interactive perseus-input-size-normal"
104
- spellcheck="false"
102
+ class="input_1t4b01j-o_O-LabelMedium_1rew30o-o_O-default_1r2dwp3"
103
+ id="input-with-examples-bnVtZXJpYy1pbnB1dCAx"
105
104
  type="text"
106
105
  value=""
107
106
  />
@@ -1489,8 +1489,25 @@ exports[`grapher widget should snapshot question with multiple graph types: init
1489
1489
  style="padding-bottom: 100%;"
1490
1490
  />
1491
1491
  <span
1492
- style="background: url(/images/spinner.gif) no-repeat; background-position: center; width: 100%; height: 100%; position: absolute; min-width: 20px;"
1493
- />
1492
+ style="top: 0px; left: 0px; width: 100%; height: 100%; position: absolute; min-width: 20px; display: flex; justify-content: center; align-content: center;"
1493
+ >
1494
+ <div
1495
+ class="default_xu2jcg-o_O-spinnerContainer_agrn11"
1496
+ >
1497
+ <svg
1498
+ height="48"
1499
+ viewBox="0 0 48 48"
1500
+ width="48"
1501
+ xmlns="http://www.w3.org/2000/svg"
1502
+ >
1503
+ <path
1504
+ class="loadingSpinner_1dvgeb3-o_O-inlineStyles_1kzk0y9"
1505
+ d="M44.19 23.455a1.91 1.91 0 1 1 3.801 0h.003c.004.18.006.363.006.545 0 13.255-10.745 24-24 24S0 37.255 0 24 10.745 0 24 0c.182 0 .364.002.545.006V.01a1.91 1.91 0 1 1 0 3.801v.015A20.564 20.564 0 0 0 24 3.818C12.854 3.818 3.818 12.854 3.818 24c0 11.146 9.036 20.182 20.182 20.182 11.146 0 20.182-9.036 20.182-20.182 0-.182-.003-.364-.007-.545h.015z"
1506
+ fill-rule="nonzero"
1507
+ />
1508
+ </svg>
1509
+ </div>
1510
+ </span>
1494
1511
  </div>
1495
1512
  <div
1496
1513
  class="graphie-container"