@pie-element/ebsr 12.3.4-next.0 → 13.0.0-beta.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 (92) hide show
  1. package/configure/lib/defaults.js +23 -36
  2. package/configure/lib/defaults.js.map +1 -1
  3. package/configure/lib/index.js +114 -202
  4. package/configure/lib/index.js.map +1 -1
  5. package/configure/lib/main.js +188 -271
  6. package/configure/lib/main.js.map +1 -1
  7. package/configure/node_modules/@pie-element/multiple-choice/CHANGELOG.json +1972 -0
  8. package/configure/node_modules/@pie-element/multiple-choice/CHANGELOG.md +4213 -0
  9. package/configure/node_modules/@pie-element/multiple-choice/PRINT.md +35 -0
  10. package/configure/node_modules/@pie-element/multiple-choice/README.md +56 -0
  11. package/configure/node_modules/@pie-element/multiple-choice/choice.png +0 -0
  12. package/configure/node_modules/@pie-element/multiple-choice/configure/CHANGELOG.json +1387 -0
  13. package/configure/node_modules/@pie-element/multiple-choice/configure/CHANGELOG.md +3351 -0
  14. package/configure/node_modules/@pie-element/multiple-choice/configure/lib/__tests__/root.test.js +248 -0
  15. package/configure/node_modules/@pie-element/multiple-choice/configure/lib/defaults.js +200 -0
  16. package/configure/node_modules/@pie-element/multiple-choice/configure/lib/defaults.js.map +1 -0
  17. package/configure/node_modules/@pie-element/multiple-choice/configure/lib/index.js +211 -0
  18. package/configure/node_modules/@pie-element/multiple-choice/configure/lib/index.js.map +1 -0
  19. package/configure/node_modules/@pie-element/multiple-choice/configure/lib/main.js +477 -0
  20. package/configure/node_modules/@pie-element/multiple-choice/configure/lib/main.js.map +1 -0
  21. package/configure/node_modules/@pie-element/multiple-choice/configure/lib/utils.js +18 -0
  22. package/configure/node_modules/@pie-element/multiple-choice/configure/lib/utils.js.map +1 -0
  23. package/configure/node_modules/@pie-element/multiple-choice/configure/package.json +22 -0
  24. package/configure/node_modules/@pie-element/multiple-choice/controller/CHANGELOG.json +527 -0
  25. package/configure/node_modules/@pie-element/multiple-choice/controller/CHANGELOG.md +2316 -0
  26. package/configure/node_modules/@pie-element/multiple-choice/controller/lib/__tests__/index.test.js +520 -0
  27. package/configure/node_modules/@pie-element/multiple-choice/controller/lib/__tests__/utils.test.js +8 -0
  28. package/configure/node_modules/@pie-element/multiple-choice/controller/lib/defaults.js +33 -0
  29. package/configure/node_modules/@pie-element/multiple-choice/controller/lib/defaults.js.map +1 -0
  30. package/configure/node_modules/@pie-element/multiple-choice/controller/lib/index.js +251 -0
  31. package/configure/node_modules/@pie-element/multiple-choice/controller/lib/index.js.map +1 -0
  32. package/configure/node_modules/@pie-element/multiple-choice/controller/lib/utils.js +16 -0
  33. package/configure/node_modules/@pie-element/multiple-choice/controller/lib/utils.js.map +1 -0
  34. package/configure/node_modules/@pie-element/multiple-choice/controller/package.json +15 -0
  35. package/configure/node_modules/@pie-element/multiple-choice/docs/config-schema.json +2993 -0
  36. package/configure/node_modules/@pie-element/multiple-choice/docs/config-schema.json.md +2217 -0
  37. package/configure/node_modules/@pie-element/multiple-choice/docs/demo/config.js +8 -0
  38. package/configure/node_modules/@pie-element/multiple-choice/docs/demo/generate.js +61 -0
  39. package/configure/node_modules/@pie-element/multiple-choice/docs/demo/index.html +1 -0
  40. package/configure/node_modules/@pie-element/multiple-choice/docs/demo/pie.manifest.json +11 -0
  41. package/configure/node_modules/@pie-element/multiple-choice/docs/demo/session.js +7 -0
  42. package/configure/node_modules/@pie-element/multiple-choice/docs/pie-schema.json +1332 -0
  43. package/configure/node_modules/@pie-element/multiple-choice/docs/pie-schema.json.md +1015 -0
  44. package/configure/node_modules/@pie-element/multiple-choice/lib/__tests__/choice-input-test.js +117 -0
  45. package/configure/node_modules/@pie-element/multiple-choice/lib/__tests__/index-test.js +151 -0
  46. package/configure/node_modules/@pie-element/multiple-choice/lib/__tests__/key-events-test.js +95 -0
  47. package/configure/node_modules/@pie-element/multiple-choice/lib/__tests__/multiple-choice-test.js +223 -0
  48. package/configure/node_modules/@pie-element/multiple-choice/lib/__tests__/session-updater-test.js +70 -0
  49. package/configure/node_modules/@pie-element/multiple-choice/lib/choice-input.js +370 -0
  50. package/configure/node_modules/@pie-element/multiple-choice/lib/choice-input.js.map +1 -0
  51. package/configure/node_modules/@pie-element/multiple-choice/lib/choice.js +197 -0
  52. package/configure/node_modules/@pie-element/multiple-choice/lib/choice.js.map +1 -0
  53. package/configure/node_modules/@pie-element/multiple-choice/lib/feedback-tick.js +130 -0
  54. package/configure/node_modules/@pie-element/multiple-choice/lib/feedback-tick.js.map +1 -0
  55. package/configure/node_modules/@pie-element/multiple-choice/lib/index.js +292 -0
  56. package/configure/node_modules/@pie-element/multiple-choice/lib/index.js.map +1 -0
  57. package/configure/node_modules/@pie-element/multiple-choice/lib/main.js +54 -0
  58. package/configure/node_modules/@pie-element/multiple-choice/lib/main.js.map +1 -0
  59. package/configure/node_modules/@pie-element/multiple-choice/lib/multiple-choice.js +386 -0
  60. package/configure/node_modules/@pie-element/multiple-choice/lib/multiple-choice.js.map +1 -0
  61. package/configure/node_modules/@pie-element/multiple-choice/lib/print.js +92 -0
  62. package/configure/node_modules/@pie-element/multiple-choice/lib/print.js.map +1 -0
  63. package/configure/node_modules/@pie-element/multiple-choice/lib/session-updater.js +37 -0
  64. package/configure/node_modules/@pie-element/multiple-choice/lib/session-updater.js.map +1 -0
  65. package/configure/node_modules/@pie-element/multiple-choice/package.json +39 -0
  66. package/configure/package.json +9 -6
  67. package/configure/src/__tests__/index.test.js +99 -108
  68. package/configure/src/index.js +13 -6
  69. package/configure/src/main.jsx +14 -18
  70. package/controller/lib/defaults.js +20 -32
  71. package/controller/lib/defaults.js.map +1 -1
  72. package/controller/lib/index.js +224 -349
  73. package/controller/lib/index.js.map +1 -1
  74. package/controller/lib/utils.js +4 -18
  75. package/controller/lib/utils.js.map +1 -1
  76. package/controller/package.json +3 -3
  77. package/lib/index.js +113 -181
  78. package/lib/index.js.map +1 -1
  79. package/lib/print.js +120 -204
  80. package/lib/print.js.map +1 -1
  81. package/package.json +5 -9
  82. package/src/__tests__/index.test.js +18 -5
  83. package/configure/src/__tests__/__snapshots__/index.test.js.snap +0 -83
  84. package/module/configure.js +0 -1
  85. package/module/controller.js +0 -6469
  86. package/module/demo.js +0 -77
  87. package/module/element.js +0 -1
  88. package/module/index.html +0 -21
  89. package/module/manifest.json +0 -14
  90. package/module/print-demo.js +0 -115
  91. package/module/print.html +0 -18
  92. package/module/print.js +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"print.js","names":["_react","_interopRequireDefault","require","_client","_debounce","_cloneDeep","_main","_mathRendering","_debug","log","debug","preparePrintModel","model","opts","instr","role","prompt","promptEnabled","undefined","teacherInstructions","teacherInstructionsEnabled","showTeacherInstructions","alwaysShowCorrect","mode","disabled","animationsDisabled","lockChoiceOrder","choicesLayout","choices","cloneDeep","map","c","rationale","rationaleEnabled","hideTick","feedback","keyMode","choicePrefix","MultipleChoicePrint","HTMLElement","constructor","_options","_model","_session","_root","_rerender","debounce","printModel","element","React","createElement","Main","session","options","createRoot","render","queueMicrotask","renderMath","leading","trailing","o","s","connectedCallback","disconnectedCallback","unmount","exports","default"],"sources":["../src/print.js"],"sourcesContent":["import React from 'react';\nimport { createRoot } from 'react-dom/client';\nimport debounce from 'lodash/debounce';\nimport cloneDeep from 'lodash/cloneDeep';\nimport Main from './main';\nimport { renderMath } from '@pie-lib/math-rendering';\nimport debug from 'debug';\n\nconst log = debug('pie-element:multiple-choice:print');\n\n/**\n * Live in same package as main element - so we can access some of the shared comps!\n *\n * - update pslb to build print if src/print.js is there\n * - update demo el\n * - get configure/controller building\n */\n\nconst preparePrintModel = (model, opts) => {\n const instr = opts.role === 'instructor';\n\n model.prompt = model.promptEnabled !== false ? model.prompt : undefined;\n model.teacherInstructions =\n instr && model.teacherInstructionsEnabled !== false ? model.teacherInstructions : undefined;\n model.showTeacherInstructions = instr;\n model.alwaysShowCorrect = instr;\n model.mode = instr ? 'evaluate' : model.mode;\n\n model.disabled = true;\n model.animationsDisabled = true;\n model.lockChoiceOrder = true;\n model.choicesLayout = model.choicesLayout || 'vertical';\n\n const choices = cloneDeep(model.choices);\n\n model.choices = choices.map((c) => {\n c.rationale = instr && model.rationaleEnabled !== false ? c.rationale : undefined;\n c.hideTick = instr;\n c.feedback = undefined;\n return c;\n });\n\n model.keyMode = model.choicePrefix || 'letters';\n\n return model;\n};\n\nexport default class MultipleChoicePrint extends HTMLElement {\n constructor() {\n super();\n this._options = null;\n this._model = null;\n this._session = [];\n this._root = null;\n this._rerender = debounce(\n () => {\n if (this._model && this._session) {\n const printModel = preparePrintModel(this._model, this._options);\n\n const element =\n this._options &&\n React.createElement(Main, {\n model: printModel,\n session: {},\n options: this._options,\n });\n\n if (!this._root) {\n this._root = createRoot(this);\n }\n this._root.render(element);\n queueMicrotask(() => {\n log('render complete - render math');\n renderMath(this);\n });\n } else {\n log('skip');\n }\n },\n 50,\n { leading: false, trailing: true },\n );\n }\n set options(o) {\n this._options = o;\n }\n\n set model(s) {\n this._model = s;\n this._rerender();\n }\n\n connectedCallback() {}\n\n disconnectedCallback() {\n if (this._root) {\n this._root.unmount();\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.updateSessionMetadata = updateSessionMetadata;
7
+ exports.updateSessionValue = updateSessionValue;
8
+ function updateSessionValue(session, choiceMode, data) {
9
+ session.value = session.value || [];
10
+ if (choiceMode === 'checkbox') {
11
+ if (data.selected) {
12
+ session.value = Array.from(new Set([...session.value, data.value]));
13
+ } else {
14
+ session.value = session.value.filter(v => v !== data.value);
15
+ }
16
+ }
17
+ if (choiceMode === 'radio') {
18
+ if (data.selected) {
19
+ session.value = [data.value];
20
+ } else {
21
+ session.value = [];
22
+ }
23
+ }
24
+
25
+ //update session value metadata
26
+ session.selector = data.selector; //the input method used to select the choice (e.g. mouse, keyboard)
27
+ }
28
+ function updateSessionMetadata(session, metadata) {
29
+ session.audioStartTime = session.audioStartTime || metadata.audioStartTime; //timestamp when auto-played audio started playing
30
+ session.audioEndTime = session.audioEndTime || metadata.audioEndTime; //timestamp when auto-played audio completed playing
31
+
32
+ if (!session.waitTime && session.audioStartTime && session.audioEndTime) {
33
+ // waitTime is elapsed time the user waited for auto-played audio to finish
34
+ session.waitTime = session.audioEndTime - session.audioStartTime;
35
+ }
36
+ }
37
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJ1cGRhdGVTZXNzaW9uVmFsdWUiLCJzZXNzaW9uIiwiY2hvaWNlTW9kZSIsImRhdGEiLCJ2YWx1ZSIsInNlbGVjdGVkIiwiQXJyYXkiLCJmcm9tIiwiU2V0IiwiZmlsdGVyIiwidiIsInNlbGVjdG9yIiwidXBkYXRlU2Vzc2lvbk1ldGFkYXRhIiwibWV0YWRhdGEiLCJhdWRpb1N0YXJ0VGltZSIsImF1ZGlvRW5kVGltZSIsIndhaXRUaW1lIl0sInNvdXJjZXMiOlsiLi4vc3JjL3Nlc3Npb24tdXBkYXRlci5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgZnVuY3Rpb24gdXBkYXRlU2Vzc2lvblZhbHVlKHNlc3Npb24sIGNob2ljZU1vZGUsIGRhdGEpIHtcbiAgc2Vzc2lvbi52YWx1ZSA9IHNlc3Npb24udmFsdWUgfHwgW107XG4gIGlmIChjaG9pY2VNb2RlID09PSAnY2hlY2tib3gnKSB7XG4gICAgaWYgKGRhdGEuc2VsZWN0ZWQpIHtcbiAgICAgIHNlc3Npb24udmFsdWUgPSBBcnJheS5mcm9tKG5ldyBTZXQoWy4uLnNlc3Npb24udmFsdWUsIGRhdGEudmFsdWVdKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNlc3Npb24udmFsdWUgPSBzZXNzaW9uLnZhbHVlLmZpbHRlcih2ID0+IHYgIT09IGRhdGEudmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChjaG9pY2VNb2RlID09PSAncmFkaW8nKSB7XG4gICAgaWYgKGRhdGEuc2VsZWN0ZWQpIHtcbiAgICAgIHNlc3Npb24udmFsdWUgPSBbZGF0YS52YWx1ZV07XG4gICAgfSBlbHNlIHtcbiAgICAgIHNlc3Npb24udmFsdWUgPSBbXTtcbiAgICB9XG4gIH1cbiAgXG4gIC8vdXBkYXRlIHNlc3Npb24gdmFsdWUgbWV0YWRhdGFcbiAgc2Vzc2lvbi5zZWxlY3RvciA9IGRhdGEuc2VsZWN0b3I7IC8vdGhlIGlucHV0IG1ldGhvZCB1c2VkIHRvIHNlbGVjdCB0aGUgY2hvaWNlIChlLmcuIG1vdXNlLCBrZXlib2FyZClcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZVNlc3Npb25NZXRhZGF0YShzZXNzaW9uLCBtZXRhZGF0YSkge1xuICBzZXNzaW9uLmF1ZGlvU3RhcnRUaW1lID0gc2Vzc2lvbi5hdWRpb1N0YXJ0VGltZSB8fCBtZXRhZGF0YS5hdWRpb1N0YXJ0VGltZTsgLy90aW1lc3RhbXAgd2hlbiBhdXRvLXBsYXllZCBhdWRpbyBzdGFydGVkIHBsYXlpbmdcbiAgc2Vzc2lvbi5hdWRpb0VuZFRpbWUgPSBzZXNzaW9uLmF1ZGlvRW5kVGltZSB8fCBtZXRhZGF0YS5hdWRpb0VuZFRpbWU7IC8vdGltZXN0YW1wIHdoZW4gYXV0by1wbGF5ZWQgYXVkaW8gY29tcGxldGVkIHBsYXlpbmdcbiAgXG4gIGlmKCFzZXNzaW9uLndhaXRUaW1lICYmIHNlc3Npb24uYXVkaW9TdGFydFRpbWUgJiYgc2Vzc2lvbi5hdWRpb0VuZFRpbWUpIHtcbiAgICAvLyB3YWl0VGltZSBpcyBlbGFwc2VkIHRpbWUgdGhlIHVzZXIgd2FpdGVkIGZvciBhdXRvLXBsYXllZCBhdWRpbyB0byBmaW5pc2hcbiAgICBzZXNzaW9uLndhaXRUaW1lID0gKHNlc3Npb24uYXVkaW9FbmRUaW1lIC0gc2Vzc2lvbi5hdWRpb1N0YXJ0VGltZSk7XG4gIH1cbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFPLFNBQVNBLGtCQUFrQkEsQ0FBQ0MsT0FBTyxFQUFFQyxVQUFVLEVBQUVDLElBQUksRUFBRTtFQUM1REYsT0FBTyxDQUFDRyxLQUFLLEdBQUdILE9BQU8sQ0FBQ0csS0FBSyxJQUFJLEVBQUU7RUFDbkMsSUFBSUYsVUFBVSxLQUFLLFVBQVUsRUFBRTtJQUM3QixJQUFJQyxJQUFJLENBQUNFLFFBQVEsRUFBRTtNQUNqQkosT0FBTyxDQUFDRyxLQUFLLEdBQUdFLEtBQUssQ0FBQ0MsSUFBSSxDQUFDLElBQUlDLEdBQUcsQ0FBQyxDQUFDLEdBQUdQLE9BQU8sQ0FBQ0csS0FBSyxFQUFFRCxJQUFJLENBQUNDLEtBQUssQ0FBQyxDQUFDLENBQUM7SUFDckUsQ0FBQyxNQUFNO01BQ0xILE9BQU8sQ0FBQ0csS0FBSyxHQUFHSCxPQUFPLENBQUNHLEtBQUssQ0FBQ0ssTUFBTSxDQUFDQyxDQUFDLElBQUlBLENBQUMsS0FBS1AsSUFBSSxDQUFDQyxLQUFLLENBQUM7SUFDN0Q7RUFDRjtFQUVBLElBQUlGLFVBQVUsS0FBSyxPQUFPLEVBQUU7SUFDMUIsSUFBSUMsSUFBSSxDQUFDRSxRQUFRLEVBQUU7TUFDakJKLE9BQU8sQ0FBQ0csS0FBSyxHQUFHLENBQUNELElBQUksQ0FBQ0MsS0FBSyxDQUFDO0lBQzlCLENBQUMsTUFBTTtNQUNMSCxPQUFPLENBQUNHLEtBQUssR0FBRyxFQUFFO0lBQ3BCO0VBQ0Y7O0VBRUE7RUFDQUgsT0FBTyxDQUFDVSxRQUFRLEdBQUdSLElBQUksQ0FBQ1EsUUFBUSxDQUFDLENBQUM7QUFDcEM7QUFFTyxTQUFTQyxxQkFBcUJBLENBQUNYLE9BQU8sRUFBRVksUUFBUSxFQUFFO0VBQ3ZEWixPQUFPLENBQUNhLGNBQWMsR0FBR2IsT0FBTyxDQUFDYSxjQUFjLElBQUlELFFBQVEsQ0FBQ0MsY0FBYyxDQUFDLENBQUM7RUFDNUViLE9BQU8sQ0FBQ2MsWUFBWSxHQUFHZCxPQUFPLENBQUNjLFlBQVksSUFBSUYsUUFBUSxDQUFDRSxZQUFZLENBQUMsQ0FBQzs7RUFFdEUsSUFBRyxDQUFDZCxPQUFPLENBQUNlLFFBQVEsSUFBSWYsT0FBTyxDQUFDYSxjQUFjLElBQUliLE9BQU8sQ0FBQ2MsWUFBWSxFQUFFO0lBQ3RFO0lBQ0FkLE9BQU8sQ0FBQ2UsUUFBUSxHQUFJZixPQUFPLENBQUNjLFlBQVksR0FBR2QsT0FBTyxDQUFDYSxjQUFlO0VBQ3BFO0FBQ0YiLCJpZ25vcmVMaXN0IjpbXX0=
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-updater.js","names":["updateSessionValue","session","choiceMode","data","value","selected","Array","from","Set","filter","v","selector","updateSessionMetadata","metadata","audioStartTime","audioEndTime","waitTime"],"sources":["../src/session-updater.js"],"sourcesContent":["export function updateSessionValue(session, choiceMode, data) {\n session.value = session.value || [];\n if (choiceMode === 'checkbox') {\n if (data.selected) {\n session.value = Array.from(new Set([...session.value, data.value]));\n } else {\n session.value = session.value.filter(v => v !== data.value);\n }\n }\n\n if (choiceMode === 'radio') {\n if (data.selected) {\n session.value = [data.value];\n } else {\n session.value = [];\n }\n }\n \n //update session value metadata\n session.selector = data.selector; //the input method used to select the choice (e.g. mouse, keyboard)\n}\n\nexport function updateSessionMetadata(session, metadata) {\n session.audioStartTime = session.audioStartTime || metadata.audioStartTime; //timestamp when auto-played audio started playing\n session.audioEndTime = session.audioEndTime || metadata.audioEndTime; //timestamp when auto-played audio completed playing\n \n if(!session.waitTime && session.audioStartTime && session.audioEndTime) {\n // waitTime is elapsed time the user waited for auto-played audio to finish\n session.waitTime = (session.audioEndTime - session.audioStartTime);\n }\n}\n"],"mappings":";;;;;;;AAAO,SAASA,kBAAkBA,CAACC,OAAO,EAAEC,UAAU,EAAEC,IAAI,EAAE;EAC5DF,OAAO,CAACG,KAAK,GAAGH,OAAO,CAACG,KAAK,IAAI,EAAE;EACnC,IAAIF,UAAU,KAAK,UAAU,EAAE;IAC7B,IAAIC,IAAI,CAACE,QAAQ,EAAE;MACjBJ,OAAO,CAACG,KAAK,GAAGE,KAAK,CAACC,IAAI,CAAC,IAAIC,GAAG,CAAC,CAAC,GAAGP,OAAO,CAACG,KAAK,EAAED,IAAI,CAACC,KAAK,CAAC,CAAC,CAAC;IACrE,CAAC,MAAM;MACLH,OAAO,CAACG,KAAK,GAAGH,OAAO,CAACG,KAAK,CAACK,MAAM,CAACC,CAAC,IAAIA,CAAC,KAAKP,IAAI,CAACC,KAAK,CAAC;IAC7D;EACF;EAEA,IAAIF,UAAU,KAAK,OAAO,EAAE;IAC1B,IAAIC,IAAI,CAACE,QAAQ,EAAE;MACjBJ,OAAO,CAACG,KAAK,GAAG,CAACD,IAAI,CAACC,KAAK,CAAC;IAC9B,CAAC,MAAM;MACLH,OAAO,CAACG,KAAK,GAAG,EAAE;IACpB;EACF;;EAEA;EACAH,OAAO,CAACU,QAAQ,GAAGR,IAAI,CAACQ,QAAQ,CAAC,CAAC;AACpC;AAEO,SAASC,qBAAqBA,CAACX,OAAO,EAAEY,QAAQ,EAAE;EACvDZ,OAAO,CAACa,cAAc,GAAGb,OAAO,CAACa,cAAc,IAAID,QAAQ,CAACC,cAAc,CAAC,CAAC;EAC5Eb,OAAO,CAACc,YAAY,GAAGd,OAAO,CAACc,YAAY,IAAIF,QAAQ,CAACE,YAAY,CAAC,CAAC;;EAEtE,IAAG,CAACd,OAAO,CAACe,QAAQ,IAAIf,OAAO,CAACa,cAAc,IAAIb,OAAO,CAACc,YAAY,EAAE;IACtE;IACAd,OAAO,CAACe,QAAQ,GAAIf,OAAO,CAACc,YAAY,GAAGd,OAAO,CAACa,cAAe;EACpE;AACF","ignoreList":[]}
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@pie-element/multiple-choice",
3
+ "repository": "pie-framework/pie-elements",
4
+ "version": "11.2.0-mui-update.4",
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "dependencies": {
9
+ "@emotion/react": "^11.14.0",
10
+ "@emotion/style": "^0.8.0",
11
+ "@mui/icons-material": "^7.3.4",
12
+ "@mui/material": "^7.3.4",
13
+ "@pie-framework/pie-player-events": "^0.1.0",
14
+ "@pie-lib/correct-answer-toggle": "2.32.1-mui-update.0",
15
+ "@pie-lib/math-rendering": "3.33.1-mui-update.0",
16
+ "@pie-lib/render-ui": "4.42.1-mui-update.0",
17
+ "@pie-lib/translator": "2.31.1-mui-update.0",
18
+ "classnames": "^2.2.5",
19
+ "debug": "^4.1.1",
20
+ "enzyme-to-json": "^3.3.3",
21
+ "lodash": "^4.17.10",
22
+ "prop-types": "^15.6.1",
23
+ "react": "18.2.0",
24
+ "react-dom": "18.2.0",
25
+ "react-test-renderer": "18.2.0",
26
+ "react-transition-group": "^2.3.1"
27
+ },
28
+ "gitHead": "0e14ff981bcdc8a89a0e58484026496701bfdbc3",
29
+ "scripts": {
30
+ "postpublish": "../../scripts/postpublish"
31
+ },
32
+ "main": "lib/index.js",
33
+ "module": "src/index.js",
34
+ "exports": {
35
+ ".": "./src/index.js",
36
+ "./print": "./src/print.js",
37
+ "./configure/lib": "./configure/lib/index.js"
38
+ }
39
+ }
@@ -1,20 +1,23 @@
1
1
  {
2
2
  "name": "@pie-element/ebsr-configure",
3
3
  "private": true,
4
- "version": "11.3.3",
4
+ "version": "12.0.0-beta.0",
5
5
  "description": "",
6
6
  "main": "lib/index.js",
7
7
  "module": "src/index.js",
8
8
  "author": "",
9
9
  "dependencies": {
10
- "@material-ui/core": "^3.9.2",
11
- "@pie-element/multiple-choice": "^11.4.3",
10
+ "@emotion/react": "^11.14.0",
11
+ "@emotion/style": "^0.8.0",
12
+ "@mui/icons-material": "^7.3.4",
13
+ "@mui/material": "^7.3.4",
14
+ "@pie-element/multiple-choice": "12.0.0-beta.0",
12
15
  "@pie-framework/pie-configure-events": "^1.2.0",
13
- "@pie-lib/config-ui": "11.30.2",
16
+ "@pie-lib/config-ui": "11.30.4-next.0",
14
17
  "lodash": "^4.17.15",
15
18
  "prop-types": "^15.6.2",
16
- "react": "^16.8.1",
17
- "react-dom": "^16.8.1"
19
+ "react": "18.2.0",
20
+ "react-dom": "18.2.0"
18
21
  },
19
22
  "license": "ISC"
20
23
  }
@@ -1,23 +1,29 @@
1
1
  import React from 'react';
2
- import { mount } from 'enzyme';
2
+ import { render } from '@testing-library/react';
3
+ import { ThemeProvider, createTheme } from '@mui/material/styles';
3
4
  import { ModelUpdatedEvent } from '@pie-framework/pie-configure-events';
4
5
  import { choiceUtils as utils } from '@pie-lib/config-ui';
5
- import ReactDOM from 'react-dom';
6
+ import { createRoot } from 'react-dom/client';
6
7
  import defaults from '../defaults';
7
8
  import { Main } from '../main';
8
9
  import EbsrConfigure from '../index';
9
10
 
10
- jest.mock('react-dom', () => ({
11
- render: jest.fn(),
11
+ const mockRender = jest.fn();
12
+ const mockUnmount = jest.fn();
13
+ jest.mock('react-dom/client', () => ({
14
+ createRoot: jest.fn(() => ({
15
+ render: mockRender,
16
+ unmount: mockUnmount,
17
+ })),
12
18
  }));
13
19
 
14
20
  jest.mock('@pie-framework/pie-configure-events', () => ({
15
- ModelUpdatedEvent: (update) => {
16
- return {
17
- update,
18
- preventDefault: jest.fn(),
19
- stopImmediatePropagation: jest.fn(),
20
- };
21
+ ModelUpdatedEvent: class ModelUpdatedEvent {
22
+ constructor(update) {
23
+ this.update = update;
24
+ this.preventDefault = jest.fn();
25
+ this.stopImmediatePropagation = jest.fn();
26
+ }
21
27
  },
22
28
  }));
23
29
 
@@ -26,17 +32,19 @@ jest.mock('@pie-lib/config-ui', () => ({
26
32
  firstAvailableIndex: jest.fn(),
27
33
  },
28
34
  settings: {
29
- Panel: (props) => <div {...props} />,
35
+ Panel: (props) => <div data-testid="settings-panel" {...props} />,
30
36
  toggle: jest.fn(),
31
37
  radio: jest.fn(),
32
38
  dropdown: jest.fn(),
33
39
  },
34
40
  layout: {
35
- ConfigLayout: (props) => <div>{props.children}</div>,
41
+ ConfigLayout: (props) => <div data-testid="config-layout">{props.children}</div>,
36
42
  },
37
43
  }));
38
44
 
39
- jest.mock('@pie-element/multiple-choice/configure/lib', () => class MockConfigure {});
45
+ jest.mock('@pie-element/multiple-choice/configure/lib', () => (class MockConfigure {}));
46
+
47
+ const theme = createTheme();
40
48
 
41
49
  const PART_A = 'partA';
42
50
  const PART_B = 'partB';
@@ -110,65 +118,25 @@ describe('index', () => {
110
118
  let el;
111
119
  let onModelChanged = jest.fn();
112
120
  let onConfigurationChanged = jest.fn();
113
- let main;
114
121
 
115
122
  beforeAll(() => {
116
123
  Def = require('../index').default;
124
+
125
+ // Register the custom element if not already registered
126
+ if (!customElements.get('ebsr-configure')) {
127
+ customElements.define('ebsr-configure', Def);
128
+ }
117
129
  });
118
130
 
119
131
  beforeEach(() => {
120
- el = new Def();
132
+ jest.clearAllMocks();
133
+ el = document.createElement('ebsr-configure');
121
134
  el.model = model;
122
135
  el.configuration = defaults.configuration;
123
136
  el.onModelChanged = onModelChanged;
124
137
  el.onConfigurationChanged = onConfigurationChanged;
125
138
  el.connectedCallback();
126
139
  el.dispatchEvent = el.onModelUpdated;
127
-
128
- main = mount(
129
- <Main
130
- classes={{}}
131
- model={el._model}
132
- configuration={defaults.configuration}
133
- onConfigurationChanged={el.onConfigurationChanged}
134
- onModelChanged={el.onModelChanged}
135
- />,
136
- );
137
-
138
- // mock onModelChanged to dispatch a MODEL_UPDATED event (as multiple-choice does)
139
- main.instance().partA.onModelChanged = (m) => {
140
- const event = new ModelUpdatedEvent(m, false);
141
-
142
- el.dispatchEvent({
143
- ...event,
144
- target: {
145
- getAttribute: jest.fn().mockReturnValue('A'),
146
- },
147
- });
148
- };
149
- main.instance().partB.onModelChanged = (m) => {
150
- const event = new ModelUpdatedEvent(m, false);
151
-
152
- el.dispatchEvent({
153
- ...event,
154
- target: {
155
- getAttribute: jest.fn().mockReturnValue('B'),
156
- },
157
- });
158
- };
159
- });
160
-
161
- describe('createDefaultModel', () => {
162
- it('default-snapshot', () => {
163
- const m = EbsrConfigure.createDefaultModel({});
164
- expect(m).toMatchSnapshot();
165
- });
166
- it('with-overrides-snapshot', () => {
167
- const m = EbsrConfigure.createDefaultModel({
168
- partA: { rationale: 'foo', teacherInstructions: 'ti' },
169
- });
170
- expect(m).toMatchSnapshot();
171
- });
172
140
  });
173
141
 
174
142
  describe('set model', () => {
@@ -176,12 +144,26 @@ describe('index', () => {
176
144
  el.model = model;
177
145
 
178
146
  expect(el._model).toEqual(model);
179
- expect(ReactDOM.render).toHaveBeenCalled();
147
+ expect(createRoot).toHaveBeenCalled();
148
+ expect(mockRender).toHaveBeenCalled();
180
149
  });
181
150
 
182
151
  it('should have set the model for partA and partB', () => {
183
- expect(main.instance().partA._model).toEqual(model.partA);
184
- expect(main.instance().partB._model).toEqual(model.partB);
152
+ const { container } = render(
153
+ <ThemeProvider theme={theme}>
154
+ <Main
155
+ classes={{}}
156
+ model={el._model}
157
+ configuration={defaults.configuration}
158
+ onConfigurationChanged={el.onConfigurationChanged}
159
+ onModelChanged={el.onModelChanged}
160
+ />
161
+ </ThemeProvider>
162
+ );
163
+
164
+ expect(container).toBeInTheDocument();
165
+ expect(el._model.partA).toEqual(model.partA);
166
+ expect(el._model.partB).toEqual(model.partB);
185
167
  });
186
168
  });
187
169
 
@@ -189,24 +171,28 @@ describe('index', () => {
189
171
  it('calls ReactDOM.render', () => {
190
172
  el.configuration = defaults.configuration;
191
173
 
192
- expect(ReactDOM.render).toHaveBeenCalled();
174
+ expect(createRoot).toHaveBeenCalled();
175
+ expect(mockRender).toHaveBeenCalled();
193
176
  });
194
177
 
195
178
  it('should have set the configuration for partA and partB', () => {
196
- expect(main.instance().partA.configuration).toEqual({
197
- ...defaults.configuration.partA,
198
- partLabels: defaults.configuration.partLabels,
199
- settingsPanelDisabled: true,
200
- });
201
- expect(main.instance().partB.configuration).toEqual({
202
- ...defaults.configuration.partB,
203
- partLabels: defaults.configuration.partLabels,
204
- settingsPanelDisabled: true,
205
- });
179
+ const { container } = render(
180
+ <ThemeProvider theme={theme}>
181
+ <Main
182
+ classes={{}}
183
+ model={el._model}
184
+ configuration={defaults.configuration}
185
+ onConfigurationChanged={el.onConfigurationChanged}
186
+ onModelChanged={el.onModelChanged}
187
+ />
188
+ </ThemeProvider>
189
+ );
190
+
191
+ expect(container).toBeInTheDocument();
206
192
  });
207
193
  });
208
194
 
209
- const assetOnModelUpdated = (label, key, updatedPart, expected) => {
195
+ const assertOnModelUpdated = (label, key, updatedPart, expected) => {
210
196
  it(label, () => {
211
197
  const event = new ModelUpdatedEvent(updatedPart, false);
212
198
 
@@ -217,22 +203,23 @@ describe('index', () => {
217
203
  },
218
204
  });
219
205
 
220
- expect(ReactDOM.render).toBeCalled();
206
+ expect(createRoot).toBeCalled();
207
+ expect(mockRender).toBeCalled();
221
208
  expect(el._model[`part${key}`]).toEqual(expected);
222
209
  });
223
210
  };
224
211
 
225
212
  describe('onModelUpdated', () => {
226
- assetOnModelUpdated('dispatching MODEL_UPDATED updates model.partA', 'A', { updatedA: true }, { updatedA: true });
227
- assetOnModelUpdated('dispatching MODEL_UPDATED updates model.partB', 'B', { updatedB: true }, { updatedB: true });
213
+ assertOnModelUpdated('dispatching MODEL_UPDATED updates model.partA', 'A', { updatedA: true }, { updatedA: true });
214
+ assertOnModelUpdated('dispatching MODEL_UPDATED updates model.partB', 'B', { updatedB: true }, { updatedB: true });
228
215
 
229
- assetOnModelUpdated(
216
+ assertOnModelUpdated(
230
217
  'dispatching MODEL_UPDATED with update undefined does not update model.partA',
231
218
  'A',
232
219
  undefined,
233
220
  createDefaultModel(model).partA,
234
221
  );
235
- assetOnModelUpdated(
222
+ assertOnModelUpdated(
236
223
  'dispatching MODEL_UPDATED with update undefined does not update model.partB',
237
224
  'B',
238
225
  undefined,
@@ -240,34 +227,43 @@ describe('index', () => {
240
227
  );
241
228
  });
242
229
 
243
- const assetPartUpdate = (label, key, updatedModel) => {
230
+ const assertPartUpdate = (label, key, updatedModel) => {
244
231
  it(`${key} - ${label}`, () => {
245
- main.instance()[key].onModelChanged(updatedModel);
232
+ // Simulate the onModelChanged call for the specific part
233
+ const event = new ModelUpdatedEvent(updatedModel, false);
234
+
235
+ el.dispatchEvent({
236
+ ...event,
237
+ target: {
238
+ getAttribute: jest.fn().mockReturnValue(key === 'partA' ? 'A' : 'B'),
239
+ },
240
+ });
246
241
 
247
242
  expect(el._model[key]).toEqual(updatedModel);
248
- expect(ReactDOM.render).toBeCalled();
243
+ expect(createRoot).toBeCalled();
244
+ expect(mockRender).toBeCalled();
249
245
  });
250
246
  };
251
247
 
252
248
  describe('part update', () => {
253
- assetPartUpdate('Dispatching Model Updated Event will update Teacher Instructions', 'partA', {
249
+ assertPartUpdate('Dispatching Model Updated Event will update Teacher Instructions', 'partA', {
254
250
  ...model.partA,
255
251
  teacherInstructions: 'Part A Teacher Instructions',
256
252
  });
257
- assetPartUpdate('Dispatching Model Updated Event will update Teacher Instructions', 'partB', {
253
+ assertPartUpdate('Dispatching Model Updated Event will update Teacher Instructions', 'partB', {
258
254
  ...model.partB,
259
255
  teacherInstructions: 'Part B Teacher Instructions',
260
256
  });
261
- assetPartUpdate('Dispatching Model Updated Event will update Prompt', 'partA', {
257
+ assertPartUpdate('Dispatching Model Updated Event will update Prompt', 'partA', {
262
258
  ...model.partA,
263
259
  prompt: 'Prompt A',
264
260
  });
265
- assetPartUpdate('Dispatching Model Updated Event will update Prompt', 'partB', {
261
+ assertPartUpdate('Dispatching Model Updated Event will update Prompt', 'partB', {
266
262
  ...model.partA,
267
263
  prompt: 'Prompt B',
268
264
  });
269
265
 
270
- assetPartUpdate('Dispatching Model Updated Event will update Choices - ADD CHOICE', 'partA', {
266
+ assertPartUpdate('Dispatching Model Updated Event will update Choices - ADD CHOICE', 'partA', {
271
267
  ...model.partA,
272
268
  choices: [
273
269
  ...model.partA.choices,
@@ -283,7 +279,7 @@ describe('index', () => {
283
279
  },
284
280
  ],
285
281
  });
286
- assetPartUpdate('Dispatching Model Updated Event will update Choices - ADD CHOICE', 'partB', {
282
+ assertPartUpdate('Dispatching Model Updated Event will update Choices - ADD CHOICE', 'partB', {
287
283
  ...model.partB,
288
284
  choices: [
289
285
  ...model.partB.choices,
@@ -299,15 +295,15 @@ describe('index', () => {
299
295
  },
300
296
  ],
301
297
  });
302
- assetPartUpdate('Dispatching Model Updated Event will update Choices - REMOVE CHOICE', 'partA', {
298
+ assertPartUpdate('Dispatching Model Updated Event will update Choices - REMOVE CHOICE', 'partA', {
303
299
  ...model.partA,
304
300
  choices: model.partA.choices.splice(0, 2),
305
301
  });
306
- assetPartUpdate('Dispatching Model Updated Event will update Choices - REMOVE CHOICE', 'partB', {
302
+ assertPartUpdate('Dispatching Model Updated Event will update Choices - REMOVE CHOICE', 'partB', {
307
303
  ...model.partB,
308
304
  choices: model.partB.choices.splice(0, 2),
309
305
  });
310
- assetPartUpdate('Dispatching Model Updated Event will update Choices - CHANGE CHOICE', 'partA', {
306
+ assertPartUpdate('Dispatching Model Updated Event will update Choices - CHANGE CHOICE', 'partA', {
311
307
  ...model.partA,
312
308
  choices: model.partA.choices.splice(1, 1, {
313
309
  correct: true,
@@ -319,7 +315,7 @@ describe('index', () => {
319
315
  },
320
316
  }),
321
317
  });
322
- assetPartUpdate('Dispatching Model Updated Event will update Choices - CHANGE CHOICE', 'partB', {
318
+ assertPartUpdate('Dispatching Model Updated Event will update Choices - CHANGE CHOICE', 'partB', {
323
319
  ...model.partB,
324
320
  choices: model.partB.choices.splice(1, 1, {
325
321
  correct: true,
@@ -332,40 +328,35 @@ describe('index', () => {
332
328
  }),
333
329
  });
334
330
 
335
- assetPartUpdate('Dispatching Model Updated Event will update Choices', 'partA', { ...model.partA, choices: [] });
336
- assetPartUpdate('Dispatching Model Updated Event will update Choices', 'partB', { ...model.partB, choices: [] });
331
+ assertPartUpdate('Dispatching Model Updated Event will update Choices', 'partA', { ...model.partA, choices: [] });
332
+ assertPartUpdate('Dispatching Model Updated Event will update Choices', 'partB', { ...model.partB, choices: [] });
337
333
  });
338
334
  });
339
335
 
340
336
  describe('main', () => {
341
337
  let Def;
342
338
  let el;
343
- let main;
344
339
 
345
340
  beforeAll(() => {
346
341
  Def = require('../index').default;
342
+
343
+ // Register the custom element if not already registered
344
+ if (!customElements.get('ebsr-configure')) {
345
+ customElements.define('ebsr-configure', Def);
346
+ }
347
347
  });
348
348
 
349
349
  beforeEach(() => {
350
- el = new Def();
350
+ jest.clearAllMocks();
351
+ el = document.createElement('ebsr-configure');
351
352
  el.model = model;
352
353
  el.configuration = defaults.configuration;
353
354
  el.dispatchEvent = el.onModelUpdated;
354
-
355
- main = mount(
356
- <Main
357
- classes={{}}
358
- model={el._model}
359
- configuration={defaults.configuration}
360
- onConfigurationChanged={el.onConfigurationChanged}
361
- onModelChanged={el.onModelChanged}
362
- />,
363
- );
364
355
  });
365
356
 
366
357
  const assertOnModelChanged = (label, updatedModel, expected) => {
367
358
  it(label, () => {
368
- main.instance().props.onModelChanged(updatedModel);
359
+ el.onModelChanged(updatedModel);
369
360
 
370
361
  expect(el._model).toEqual(createDefaultModel(model, expected));
371
362
  });
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import ReactDOM from 'react-dom';
2
+ import { createRoot } from 'react-dom/client';
3
3
  import { ModelUpdatedEvent } from '@pie-framework/pie-configure-events';
4
4
  import MultipleChoiceConfigure from '@pie-element/multiple-choice/configure/lib';
5
5
  import defaults from 'lodash/defaults';
@@ -50,6 +50,7 @@ export default class EbsrConfigure extends HTMLElement {
50
50
 
51
51
  constructor() {
52
52
  super();
53
+ this._root = null;
53
54
 
54
55
  this._model = EbsrConfigure.createDefaultModel();
55
56
 
@@ -150,10 +151,6 @@ export default class EbsrConfigure extends HTMLElement {
150
151
  this._render();
151
152
  }
152
153
 
153
- disconnectedCallback() {
154
- this.removeEventListener(MODEL_UPDATED, this.onModelUpdated);
155
- }
156
-
157
154
  _render() {
158
155
  let element = React.createElement(Main, {
159
156
  model: this._model,
@@ -162,6 +159,16 @@ export default class EbsrConfigure extends HTMLElement {
162
159
  onConfigurationChanged: this.onConfigurationChanged,
163
160
  });
164
161
 
165
- ReactDOM.render(element, this);
162
+ if (!this._root) {
163
+ this._root = createRoot(this);
164
+ }
165
+ this._root.render(element);
166
+ }
167
+
168
+ disconnectedCallback() {
169
+ this.removeEventListener(MODEL_UPDATED, this.onModelUpdated);
170
+ if (this._root) {
171
+ this._root.unmount();
172
+ }
166
173
  }
167
174
  }
@@ -1,23 +1,21 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { settings, layout } from '@pie-lib/config-ui';
4
- import { withStyles } from '@material-ui/core/styles';
4
+ import { styled } from '@mui/material/styles';
5
5
 
6
6
  const { Panel, toggle, radio, dropdown } = settings;
7
7
 
8
- const styles = (theme) => ({
9
- partLabel: {
10
- paddingBottom: theme.spacing.unit * 2,
11
- },
12
- divider: {
13
- flex: 1,
14
- height: theme.spacing.unit * 2.5,
15
- },
16
- });
8
+ const PartLabel = styled('div')(({ theme }) => ({
9
+ paddingBottom: theme.spacing(2),
10
+ }));
11
+
12
+ const Divider = styled('div')(({ theme }) => ({
13
+ flex: 1,
14
+ height: theme.spacing(2.5),
15
+ }));
17
16
 
18
17
  export class Main extends React.Component {
19
18
  static propTypes = {
20
- classes: PropTypes.object,
21
19
  configuration: PropTypes.object,
22
20
  model: PropTypes.object,
23
21
  onModelChanged: PropTypes.func,
@@ -61,7 +59,7 @@ export class Main extends React.Component {
61
59
  };
62
60
 
63
61
  render() {
64
- const { classes, model, configuration, onConfigurationChanged } = this.props;
62
+ const { model, configuration, onConfigurationChanged } = this.props;
65
63
  const { partLabelType, partA: modelPartA, partB: modelPartB, extraCSSRules } = model;
66
64
  const {
67
65
  contentDimensions = {},
@@ -188,7 +186,7 @@ export class Main extends React.Component {
188
186
  />
189
187
  }
190
188
  >
191
- {model.partLabels && <div className={classes.partLabel}>{firstPart}</div>}
189
+ {model.partLabels && <PartLabel>{firstPart}</PartLabel>}
192
190
  <ebsr-multiple-choice-configure
193
191
  id="A"
194
192
  key="partA"
@@ -208,9 +206,9 @@ export class Main extends React.Component {
208
206
  }}
209
207
  />
210
208
 
211
- <div className={classes.divider} />
209
+ <Divider />
212
210
 
213
- {model.partLabels && <div className={classes.partLabel}>{secondPart}</div>}
211
+ {model.partLabels && <PartLabel>{secondPart}</PartLabel>}
214
212
  <ebsr-multiple-choice-configure
215
213
  id="B"
216
214
  key="partB"
@@ -234,6 +232,4 @@ export class Main extends React.Component {
234
232
  }
235
233
  }
236
234
 
237
- const Styled = withStyles(styles)(Main);
238
-
239
- export default Styled;
235
+ export default Main;