@pie-element/multiple-choice 9.7.4-next.3 → 9.7.4-next.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/configure/package.json +1 -1
- package/controller/lib/index.js +2 -1
- package/controller/lib/index.js.map +1 -1
- package/controller/package.json +1 -1
- package/docs/pie-schema.json +11 -0
- package/docs/pie-schema.json.md +10 -0
- package/lib/index.js +88 -2
- package/lib/index.js.map +1 -1
- package/lib/multiple-choice.js +5 -2
- package/lib/multiple-choice.js.map +1 -1
- package/module/configure.js +1 -1
- package/module/controller.js +1 -0
- package/module/element.js +83 -19
- package/module/manifest.json +1 -1
- package/module/print.js +19 -17
- package/package.json +3 -3
package/configure/package.json
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"@material-ui/core": "^3.9.2",
|
|
9
9
|
"@material-ui/icons": "^3.0.1",
|
|
10
10
|
"@pie-framework/pie-configure-events": "^1.3.0",
|
|
11
|
-
"@pie-lib/pie-toolbox": "2.
|
|
11
|
+
"@pie-lib/pie-toolbox": "2.8.0",
|
|
12
12
|
"debug": "^3.1.0",
|
|
13
13
|
"lodash": "^4.17.15",
|
|
14
14
|
"prop-types": "^15.6.2",
|
package/controller/lib/index.js
CHANGED
|
@@ -150,7 +150,8 @@ function _model() {
|
|
|
150
150
|
isSelectionButtonBelow: normalizedQuestion.isSelectionButtonBelow,
|
|
151
151
|
selectedAnswerBackgroundColor: normalizedQuestion.selectedAnswerBackgroundColor || 'initial',
|
|
152
152
|
minSelections: normalizedQuestion.minSelections,
|
|
153
|
-
maxSelections: normalizedQuestion.maxSelections
|
|
153
|
+
maxSelections: normalizedQuestion.maxSelections,
|
|
154
|
+
autoplayAudioEnabled: normalizedQuestion.autoplayAudioEnabled
|
|
154
155
|
};
|
|
155
156
|
_ref4 = env || {}, role = _ref4.role, mode = _ref4.mode;
|
|
156
157
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.js"],"names":["prepareChoice","model","env","defaultFeedback","choice","role","mode","out","label","value","rationale","rationaleEnabled","correct","feedbackEnabled","feedbackType","feedback","type","createDefaultModel","Promise","resolve","defaults","normalize","question","verticalMode","choicesLayout","questionProps","session","updateSession","normalizedQuestion","Object","assign","incorrect","choices","map","lockChoiceOrder","disabled","prompt","promptEnabled","gridColumns","choiceMode","keyMode","choicePrefix","responseCorrect","undefined","language","extraCSSRules","fontSizeFactor","isSelectionButtonBelow","selectedAnswerBackgroundColor","minSelections","maxSelections","teacherInstructions","teacherInstructionsEnabled","getScore","config","selectedChoices","correctChoices","filter","ch","score","reduce","acc","selectedChoice","find","length","str","parseFloat","toFixed","outcome","empty","partialScoringEnabled","partialScoring","enabled","createCorrectResponseSession","id","c","getInnerText","html","replaceAll","getContent","replace","validate","minAnswerChoices","maxAnswerChoices","reversedChoices","reverse","choicesErrors","rationaleErrors","errors","forEach","field","required","hasCorrectResponse","index","identicalAnswer","slice","some","nbOfChoices","answerChoices","correctResponse"],"mappings":"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","sourcesContent":["/* eslint-disable no-console */\nimport isEmpty from 'lodash/isEmpty';\nimport { isResponseCorrect } from './utils';\nimport defaults from './defaults';\nimport { lockChoices, partialScoring, getShuffledChoices } from '@pie-lib/pie-toolbox/controller-utils';\n\nconst prepareChoice = (model, env, defaultFeedback) => (choice) => {\n const { role, mode } = env || {};\n const out = {\n label: choice.label,\n value: choice.value,\n };\n\n if (role === 'instructor' && (mode === 'view' || mode === 'evaluate')) {\n out.rationale = model.rationaleEnabled ? choice.rationale : null;\n } else {\n out.rationale = null;\n }\n\n if (mode === 'evaluate') {\n out.correct = !!choice.correct;\n\n if (model.feedbackEnabled) {\n const feedbackType = (choice.feedback && choice.feedback.type) || 'none';\n\n if (feedbackType === 'default') {\n out.feedback = defaultFeedback[choice.correct ? 'correct' : 'incorrect'];\n } else if (feedbackType === 'custom') {\n out.feedback = choice.feedback.value;\n }\n }\n }\n\n return out;\n};\n\nexport function createDefaultModel(model = {}) {\n return new Promise((resolve) => resolve({ ...defaults, ...model }));\n}\n\nexport const normalize = (question) => {\n const { verticalMode, choicesLayout, ...questionProps } = question || {};\n\n return {\n ...defaults,\n ...questionProps,\n // This is used for offering support for old models which have the property verticalMode\n // Same thing is set in authoring : packages/multiple-choice/configure/src/index.jsx - createDefaultModel\n choicesLayout: choicesLayout || (verticalMode === false && 'horizontal') || defaults.choicesLayout,\n };\n};\n\n/**\n *\n * @param {*} question\n * @param {*} session\n * @param {*} env\n * @param {*} updateSession - optional - a function that will set the properties passed into it on the session.\n */\nexport async function model(question, session, env, updateSession) {\n const normalizedQuestion = normalize(question);\n\n const defaultFeedback = Object.assign(\n { correct: 'Correct', incorrect: 'Incorrect' },\n normalizedQuestion.defaultFeedback,\n );\n\n let choices = (normalizedQuestion.choices || []).map(prepareChoice(normalizedQuestion, env, defaultFeedback));\n\n const lockChoiceOrder = lockChoices(normalizedQuestion, session, env);\n\n if (!lockChoiceOrder) {\n choices = await getShuffledChoices(choices, session, updateSession, 'value');\n }\n\n const out = {\n disabled: env.mode !== 'gather',\n mode: env.mode,\n prompt: normalizedQuestion.promptEnabled ? normalizedQuestion.prompt : null,\n choicesLayout: normalizedQuestion.choicesLayout,\n gridColumns: normalizedQuestion.gridColumns,\n choiceMode: normalizedQuestion.choiceMode,\n keyMode: normalizedQuestion.choicePrefix,\n choices,\n responseCorrect: env.mode === 'evaluate' ? isResponseCorrect(normalizedQuestion, session) : undefined,\n language: normalizedQuestion.language,\n extraCSSRules: normalizedQuestion.extraCSSRules,\n fontSizeFactor: normalizedQuestion.fontSizeFactor,\n isSelectionButtonBelow: normalizedQuestion.isSelectionButtonBelow,\n selectedAnswerBackgroundColor: normalizedQuestion.selectedAnswerBackgroundColor || 'initial',\n minSelections: normalizedQuestion.minSelections,\n maxSelections: normalizedQuestion.maxSelections,\n };\n\n const { role, mode } = env || {};\n\n if (role === 'instructor' && (mode === 'view' || mode === 'evaluate')) {\n out.teacherInstructions = normalizedQuestion.teacherInstructionsEnabled\n ? normalizedQuestion.teacherInstructions\n : null;\n } else {\n out.teacherInstructions = null;\n }\n\n return out;\n}\n\nexport const getScore = (config, session) => {\n if (!session || isEmpty(session)) {\n return 0;\n }\n\n const selectedChoices = session.value || [];\n const correctChoices = (config.choices || []).filter((ch) => ch.correct);\n\n let score = selectedChoices.reduce(\n (acc, selectedChoice) => acc + (correctChoices.find((ch) => ch.value === selectedChoice) ? 1 : 0),\n 0,\n );\n\n if (correctChoices.length < selectedChoices.length) {\n score -= selectedChoices.length - correctChoices.length;\n\n if (score < 0) {\n score = 0;\n }\n }\n\n const str = correctChoices.length ? score / correctChoices.length : 0;\n\n return parseFloat(str.toFixed(2));\n};\n\n/**\n *\n * The score is partial by default for checkbox mode, allOrNothing for radio mode.\n * To disable partial scoring for checkbox mode you either set model.partialScoring = false or env.partialScoring = false. the value in `env` will\n * override the value in `model`.\n * @param {Object} model - the main model\n * @param {*} session\n * @param {Object} env\n */\nexport function outcome(model, session, env) {\n return new Promise((resolve) => {\n if (!session || isEmpty(session)) {\n resolve({ score: 0, empty: true });\n } else {\n const partialScoringEnabled = partialScoring.enabled(model, env) && model.choiceMode !== 'radio';\n const score = getScore(model, session);\n\n resolve({ score: partialScoringEnabled ? score : score === 1 ? 1 : 0, empty: false });\n }\n });\n}\n\nexport const createCorrectResponseSession = (question, env) => {\n return new Promise((resolve) => {\n if (env.mode !== 'evaluate' && env.role === 'instructor') {\n const { choices } = question || { choices: [] };\n\n resolve({\n id: '1',\n value: choices.filter((c) => c.correct).map((c) => c.value),\n });\n } else {\n resolve(null);\n }\n });\n};\n\n// remove all html tags\nconst getInnerText = (html) => (html || '').replaceAll(/<[^>]*>/g, '');\n\n// remove all html tags except img and iframe\nconst getContent = (html) => (html || '').replace(/(<(?!img|iframe)([^>]+)>)/gi, '');\n\nexport const validate = (model = {}, config = {}) => {\n const { choices } = model;\n const { minAnswerChoices = 2, maxAnswerChoices } = config;\n const reversedChoices = [...(choices || [])].reverse();\n const choicesErrors = {};\n const rationaleErrors = {};\n const errors = {};\n\n ['teacherInstructions', 'prompt'].forEach((field) => {\n if (config[field]?.required && !getContent(model[field])) {\n errors[field] = 'This field is required.';\n }\n });\n\n let hasCorrectResponse = false;\n\n reversedChoices.forEach((choice, index) => {\n const { correct, value, label, rationale } = choice;\n\n if (correct) {\n hasCorrectResponse = true;\n }\n\n if (!getContent(label)) {\n choicesErrors[value] = 'Content should not be empty.';\n } else {\n const identicalAnswer = reversedChoices.slice(index + 1).some((c) => c.label === label);\n\n if (identicalAnswer) {\n choicesErrors[value] = 'Content should be unique.';\n }\n }\n\n if (config.rationale?.required && !getContent(rationale)) {\n rationaleErrors[value] = 'This field is required.';\n }\n });\n\n const nbOfChoices = (choices || []).length;\n\n if (nbOfChoices < minAnswerChoices) {\n errors.answerChoices = `There should be at least ${minAnswerChoices} choices defined.`;\n } else if (nbOfChoices > maxAnswerChoices) {\n errors.answerChoices = `No more than ${maxAnswerChoices} choices should be defined.`;\n }\n\n if (!hasCorrectResponse) {\n errors.correctResponse = 'No correct response defined.';\n }\n\n if (!isEmpty(choicesErrors)) {\n errors.choices = choicesErrors;\n }\n\n if (!isEmpty(rationaleErrors)) {\n errors.rationale = rationaleErrors;\n }\n\n return errors;\n};\n"],"file":"index.js"}
|
|
1
|
+
{"version":3,"sources":["../src/index.js"],"names":["prepareChoice","model","env","defaultFeedback","choice","role","mode","out","label","value","rationale","rationaleEnabled","correct","feedbackEnabled","feedbackType","feedback","type","createDefaultModel","Promise","resolve","defaults","normalize","question","verticalMode","choicesLayout","questionProps","session","updateSession","normalizedQuestion","Object","assign","incorrect","choices","map","lockChoiceOrder","disabled","prompt","promptEnabled","gridColumns","choiceMode","keyMode","choicePrefix","responseCorrect","undefined","language","extraCSSRules","fontSizeFactor","isSelectionButtonBelow","selectedAnswerBackgroundColor","minSelections","maxSelections","autoplayAudioEnabled","teacherInstructions","teacherInstructionsEnabled","getScore","config","selectedChoices","correctChoices","filter","ch","score","reduce","acc","selectedChoice","find","length","str","parseFloat","toFixed","outcome","empty","partialScoringEnabled","partialScoring","enabled","createCorrectResponseSession","id","c","getInnerText","html","replaceAll","getContent","replace","validate","minAnswerChoices","maxAnswerChoices","reversedChoices","reverse","choicesErrors","rationaleErrors","errors","forEach","field","required","hasCorrectResponse","index","identicalAnswer","slice","some","nbOfChoices","answerChoices","correctResponse"],"mappings":"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","sourcesContent":["/* eslint-disable no-console */\nimport isEmpty from 'lodash/isEmpty';\nimport { isResponseCorrect } from './utils';\nimport defaults from './defaults';\nimport { lockChoices, partialScoring, getShuffledChoices } from '@pie-lib/pie-toolbox/controller-utils';\n\nconst prepareChoice = (model, env, defaultFeedback) => (choice) => {\n const { role, mode } = env || {};\n const out = {\n label: choice.label,\n value: choice.value,\n };\n\n if (role === 'instructor' && (mode === 'view' || mode === 'evaluate')) {\n out.rationale = model.rationaleEnabled ? choice.rationale : null;\n } else {\n out.rationale = null;\n }\n\n if (mode === 'evaluate') {\n out.correct = !!choice.correct;\n\n if (model.feedbackEnabled) {\n const feedbackType = (choice.feedback && choice.feedback.type) || 'none';\n\n if (feedbackType === 'default') {\n out.feedback = defaultFeedback[choice.correct ? 'correct' : 'incorrect'];\n } else if (feedbackType === 'custom') {\n out.feedback = choice.feedback.value;\n }\n }\n }\n\n return out;\n};\n\nexport function createDefaultModel(model = {}) {\n return new Promise((resolve) => resolve({ ...defaults, ...model }));\n}\n\nexport const normalize = (question) => {\n const { verticalMode, choicesLayout, ...questionProps } = question || {};\n\n return {\n ...defaults,\n ...questionProps,\n // This is used for offering support for old models which have the property verticalMode\n // Same thing is set in authoring : packages/multiple-choice/configure/src/index.jsx - createDefaultModel\n choicesLayout: choicesLayout || (verticalMode === false && 'horizontal') || defaults.choicesLayout,\n };\n};\n\n/**\n *\n * @param {*} question\n * @param {*} session\n * @param {*} env\n * @param {*} updateSession - optional - a function that will set the properties passed into it on the session.\n */\nexport async function model(question, session, env, updateSession) {\n const normalizedQuestion = normalize(question);\n\n const defaultFeedback = Object.assign(\n { correct: 'Correct', incorrect: 'Incorrect' },\n normalizedQuestion.defaultFeedback,\n );\n\n let choices = (normalizedQuestion.choices || []).map(prepareChoice(normalizedQuestion, env, defaultFeedback));\n\n const lockChoiceOrder = lockChoices(normalizedQuestion, session, env);\n\n if (!lockChoiceOrder) {\n choices = await getShuffledChoices(choices, session, updateSession, 'value');\n }\n\n const out = {\n disabled: env.mode !== 'gather',\n mode: env.mode,\n prompt: normalizedQuestion.promptEnabled ? normalizedQuestion.prompt : null,\n choicesLayout: normalizedQuestion.choicesLayout,\n gridColumns: normalizedQuestion.gridColumns,\n choiceMode: normalizedQuestion.choiceMode,\n keyMode: normalizedQuestion.choicePrefix,\n choices,\n responseCorrect: env.mode === 'evaluate' ? isResponseCorrect(normalizedQuestion, session) : undefined,\n language: normalizedQuestion.language,\n extraCSSRules: normalizedQuestion.extraCSSRules,\n fontSizeFactor: normalizedQuestion.fontSizeFactor,\n isSelectionButtonBelow: normalizedQuestion.isSelectionButtonBelow,\n selectedAnswerBackgroundColor: normalizedQuestion.selectedAnswerBackgroundColor || 'initial',\n minSelections: normalizedQuestion.minSelections,\n maxSelections: normalizedQuestion.maxSelections,\n autoplayAudioEnabled: normalizedQuestion.autoplayAudioEnabled,\n };\n\n const { role, mode } = env || {};\n\n if (role === 'instructor' && (mode === 'view' || mode === 'evaluate')) {\n out.teacherInstructions = normalizedQuestion.teacherInstructionsEnabled\n ? normalizedQuestion.teacherInstructions\n : null;\n } else {\n out.teacherInstructions = null;\n }\n\n return out;\n}\n\nexport const getScore = (config, session) => {\n if (!session || isEmpty(session)) {\n return 0;\n }\n\n const selectedChoices = session.value || [];\n const correctChoices = (config.choices || []).filter((ch) => ch.correct);\n\n let score = selectedChoices.reduce(\n (acc, selectedChoice) => acc + (correctChoices.find((ch) => ch.value === selectedChoice) ? 1 : 0),\n 0,\n );\n\n if (correctChoices.length < selectedChoices.length) {\n score -= selectedChoices.length - correctChoices.length;\n\n if (score < 0) {\n score = 0;\n }\n }\n\n const str = correctChoices.length ? score / correctChoices.length : 0;\n\n return parseFloat(str.toFixed(2));\n};\n\n/**\n *\n * The score is partial by default for checkbox mode, allOrNothing for radio mode.\n * To disable partial scoring for checkbox mode you either set model.partialScoring = false or env.partialScoring = false. the value in `env` will\n * override the value in `model`.\n * @param {Object} model - the main model\n * @param {*} session\n * @param {Object} env\n */\nexport function outcome(model, session, env) {\n return new Promise((resolve) => {\n if (!session || isEmpty(session)) {\n resolve({ score: 0, empty: true });\n } else {\n const partialScoringEnabled = partialScoring.enabled(model, env) && model.choiceMode !== 'radio';\n const score = getScore(model, session);\n\n resolve({ score: partialScoringEnabled ? score : score === 1 ? 1 : 0, empty: false });\n }\n });\n}\n\nexport const createCorrectResponseSession = (question, env) => {\n return new Promise((resolve) => {\n if (env.mode !== 'evaluate' && env.role === 'instructor') {\n const { choices } = question || { choices: [] };\n\n resolve({\n id: '1',\n value: choices.filter((c) => c.correct).map((c) => c.value),\n });\n } else {\n resolve(null);\n }\n });\n};\n\n// remove all html tags\nconst getInnerText = (html) => (html || '').replaceAll(/<[^>]*>/g, '');\n\n// remove all html tags except img and iframe\nconst getContent = (html) => (html || '').replace(/(<(?!img|iframe)([^>]+)>)/gi, '');\n\nexport const validate = (model = {}, config = {}) => {\n const { choices } = model;\n const { minAnswerChoices = 2, maxAnswerChoices } = config;\n const reversedChoices = [...(choices || [])].reverse();\n const choicesErrors = {};\n const rationaleErrors = {};\n const errors = {};\n\n ['teacherInstructions', 'prompt'].forEach((field) => {\n if (config[field]?.required && !getContent(model[field])) {\n errors[field] = 'This field is required.';\n }\n });\n\n let hasCorrectResponse = false;\n\n reversedChoices.forEach((choice, index) => {\n const { correct, value, label, rationale } = choice;\n\n if (correct) {\n hasCorrectResponse = true;\n }\n\n if (!getContent(label)) {\n choicesErrors[value] = 'Content should not be empty.';\n } else {\n const identicalAnswer = reversedChoices.slice(index + 1).some((c) => c.label === label);\n\n if (identicalAnswer) {\n choicesErrors[value] = 'Content should be unique.';\n }\n }\n\n if (config.rationale?.required && !getContent(rationale)) {\n rationaleErrors[value] = 'This field is required.';\n }\n });\n\n const nbOfChoices = (choices || []).length;\n\n if (nbOfChoices < minAnswerChoices) {\n errors.answerChoices = `There should be at least ${minAnswerChoices} choices defined.`;\n } else if (nbOfChoices > maxAnswerChoices) {\n errors.answerChoices = `No more than ${maxAnswerChoices} choices should be defined.`;\n }\n\n if (!hasCorrectResponse) {\n errors.correctResponse = 'No correct response defined.';\n }\n\n if (!isEmpty(choicesErrors)) {\n errors.choices = choicesErrors;\n }\n\n if (!isEmpty(rationaleErrors)) {\n errors.rationale = rationaleErrors;\n }\n\n return errors;\n};\n"],"file":"index.js"}
|
package/controller/package.json
CHANGED
package/docs/pie-schema.json
CHANGED
|
@@ -124,6 +124,12 @@
|
|
|
124
124
|
"type": "string",
|
|
125
125
|
"title": "toolbarEditorPosition"
|
|
126
126
|
},
|
|
127
|
+
"selectedAnswerBackgroundColor": {
|
|
128
|
+
"description": "Indicates the background color for selected choices",
|
|
129
|
+
"default": ": 'initial'",
|
|
130
|
+
"type": "string",
|
|
131
|
+
"title": "selectedAnswerBackgroundColor"
|
|
132
|
+
},
|
|
127
133
|
"lockChoiceOrder": {
|
|
128
134
|
"description": "Indicates the order of choices presented to user\nif true, answer choices will be presented in the order they are defined in the model\nIf false, answer choices may be presented in a random order (depending upon the value of the lockChoiceOrder environment variable)",
|
|
129
135
|
"type": "boolean",
|
|
@@ -213,6 +219,11 @@
|
|
|
213
219
|
"type": "number",
|
|
214
220
|
"title": "fontSizeFactor"
|
|
215
221
|
},
|
|
222
|
+
"autoplayAudioEnabled": {
|
|
223
|
+
"description": "Indicates if the audio for the prompt should autoplay",
|
|
224
|
+
"type": "boolean",
|
|
225
|
+
"title": "autoplayAudioEnabled"
|
|
226
|
+
},
|
|
216
227
|
"id": {
|
|
217
228
|
"description": "Identifier to identify the Pie Element in html markup, Must be unique within a pie item config.",
|
|
218
229
|
"type": "string",
|
package/docs/pie-schema.json.md
CHANGED
|
@@ -109,6 +109,12 @@ This element must be one of the following enum values:
|
|
|
109
109
|
|
|
110
110
|
Default: `": 'bottom'"`
|
|
111
111
|
|
|
112
|
+
# `selectedAnswerBackgroundColor` (string)
|
|
113
|
+
|
|
114
|
+
Indicates the background color for selected choices
|
|
115
|
+
|
|
116
|
+
Default: `": 'initial'"`
|
|
117
|
+
|
|
112
118
|
# `lockChoiceOrder` (boolean)
|
|
113
119
|
|
|
114
120
|
Indicates the order of choices presented to user
|
|
@@ -185,6 +191,10 @@ Indicates if the selection button and choice prefix should be positioned below t
|
|
|
185
191
|
|
|
186
192
|
Indicates font size adjustment factor
|
|
187
193
|
|
|
194
|
+
# `autoplayAudioEnabled` (boolean)
|
|
195
|
+
|
|
196
|
+
Indicates if the audio for the prompt should autoplay
|
|
197
|
+
|
|
188
198
|
# `id` (string, required)
|
|
189
199
|
|
|
190
200
|
Identifier to identify the Pie Element in html markup, Must be unique within a pie item config.
|
package/lib/index.js
CHANGED
|
@@ -45,7 +45,11 @@ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Re
|
|
|
45
45
|
|
|
46
46
|
var log = (0, _debug["default"])('pie-ui:multiple-choice');
|
|
47
47
|
|
|
48
|
-
var isComplete = function isComplete(session, model) {
|
|
48
|
+
var isComplete = function isComplete(session, model, audioComplete) {
|
|
49
|
+
if (!audioComplete) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
|
|
49
53
|
if (!session || !session.value) {
|
|
50
54
|
return false;
|
|
51
55
|
}
|
|
@@ -83,6 +87,7 @@ var MultipleChoice = /*#__PURE__*/function (_HTMLElement) {
|
|
|
83
87
|
_this = _super.call(this);
|
|
84
88
|
_this._model = null;
|
|
85
89
|
_this._session = null;
|
|
90
|
+
_this.audioComplete = false;
|
|
86
91
|
_this._rerender = (0, _debounce["default"])(function () {
|
|
87
92
|
if (_this._model && _this._session) {
|
|
88
93
|
var element = /*#__PURE__*/_react["default"].createElement(_main["default"], {
|
|
@@ -111,7 +116,7 @@ var MultipleChoice = /*#__PURE__*/function (_HTMLElement) {
|
|
|
111
116
|
trailing: true
|
|
112
117
|
});
|
|
113
118
|
_this._dispatchResponseChanged = (0, _debounce["default"])(function () {
|
|
114
|
-
_this.dispatchEvent(new _piePlayerEvents.SessionChangedEvent(_this.tagName.toLowerCase(), isComplete(_this._session, _this._model)));
|
|
119
|
+
_this.dispatchEvent(new _piePlayerEvents.SessionChangedEvent(_this.tagName.toLowerCase(), isComplete(_this._session, _this._model, _this.audioComplete)));
|
|
115
120
|
});
|
|
116
121
|
_this._dispatchModelSet = (0, _debounce["default"])(function () {
|
|
117
122
|
_this.dispatchEvent(new _piePlayerEvents.ModelSetEvent(_this.tagName.toLowerCase(), isComplete(_this._session, _this._model), _this._model !== undefined));
|
|
@@ -165,10 +170,91 @@ var MultipleChoice = /*#__PURE__*/function (_HTMLElement) {
|
|
|
165
170
|
|
|
166
171
|
this._rerender();
|
|
167
172
|
}
|
|
173
|
+
}, {
|
|
174
|
+
key: "_createAudioInfoToast",
|
|
175
|
+
value: function _createAudioInfoToast() {
|
|
176
|
+
var info = document.createElement('div');
|
|
177
|
+
info.id = 'play-audio-info';
|
|
178
|
+
info.innerHTML = 'Click anywhere to enable audio autoplay. Browser restrictions require user interaction to play audio.';
|
|
179
|
+
Object.assign(info.style, {
|
|
180
|
+
position: 'fixed',
|
|
181
|
+
bottom: '20px',
|
|
182
|
+
left: '50%',
|
|
183
|
+
transform: 'translateX(-50%)',
|
|
184
|
+
backgroundColor: '#333',
|
|
185
|
+
color: '#fff',
|
|
186
|
+
padding: '10px 20px',
|
|
187
|
+
borderRadius: '5px',
|
|
188
|
+
boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)',
|
|
189
|
+
zIndex: '1000'
|
|
190
|
+
});
|
|
191
|
+
return info;
|
|
192
|
+
}
|
|
168
193
|
}, {
|
|
169
194
|
key: "connectedCallback",
|
|
170
195
|
value: function connectedCallback() {
|
|
196
|
+
var _this2 = this;
|
|
197
|
+
|
|
171
198
|
this._rerender();
|
|
199
|
+
|
|
200
|
+
if (this._model && !this._model.autoplayAudioEnabled) {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
var observer = new MutationObserver(function (mutationsList, observer) {
|
|
205
|
+
mutationsList.forEach(function (mutation) {
|
|
206
|
+
if (mutation.type === 'childList') {
|
|
207
|
+
var audio = _this2.querySelector('audio[autoplay]');
|
|
208
|
+
|
|
209
|
+
if (!audio) return; // if the audio is paused, it means the user has not interacted with the page yet and the audio will not play
|
|
210
|
+
|
|
211
|
+
if (audio.paused && !_this2.querySelector('#play-audio-info')) {
|
|
212
|
+
// add info message as a toast to enable audio playback
|
|
213
|
+
var info = _this2._createAudioInfoToast();
|
|
214
|
+
|
|
215
|
+
_this2.appendChild(info);
|
|
216
|
+
|
|
217
|
+
var enableAudio = function enableAudio() {
|
|
218
|
+
audio.play();
|
|
219
|
+
|
|
220
|
+
_this2.removeChild(info);
|
|
221
|
+
|
|
222
|
+
document.removeEventListener('click', enableAudio);
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
document.addEventListener('click', enableAudio);
|
|
226
|
+
} // we need to listen for the playing event to remove the toast in case the audio plays because of re-rendering
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
var handlePlaying = function handlePlaying() {
|
|
230
|
+
var info = _this2.querySelector('#play-audio-info');
|
|
231
|
+
|
|
232
|
+
if (info) {
|
|
233
|
+
_this2.removeChild(info);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
audio.removeEventListener('playing', handlePlaying);
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
audio.addEventListener('playing', handlePlaying); // we need to listen for the ended event to update the isComplete state
|
|
240
|
+
|
|
241
|
+
var handleEnded = function handleEnded() {
|
|
242
|
+
_this2.audioComplete = true;
|
|
243
|
+
|
|
244
|
+
_this2._dispatchResponseChanged();
|
|
245
|
+
|
|
246
|
+
audio.removeEventListener('ended', handleEnded);
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
audio.addEventListener('ended', handleEnded);
|
|
250
|
+
observer.disconnect();
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
});
|
|
254
|
+
observer.observe(this, {
|
|
255
|
+
childList: true,
|
|
256
|
+
subtree: true
|
|
257
|
+
});
|
|
172
258
|
}
|
|
173
259
|
}]);
|
|
174
260
|
return MultipleChoice;
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.js"],"names":["log","isComplete","session","model","value","choiceMode","minSelections","maxSelections","selections","length","MultipleChoice","_model","_session","_rerender","element","React","createElement","Main","onChoiceChanged","_onChange","bind","onShowCorrectToggle","setAttribute","setLangAttribute","ReactDOM","render","leading","trailing","_dispatchResponseChanged","dispatchEvent","SessionChangedEvent","tagName","toLowerCase","_dispatchModelSet","ModelSetEvent","undefined","language","lang","slice","s","data","HTMLElement"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;;;;;AAEA,IAAMA,GAAG,GAAG,uBAAM,wBAAN,CAAZ;;AAEO,IAAMC,UAAU,GAAG,SAAbA,UAAa,CAACC,OAAD,EAAUC,KAAV,EAAoB;AAC5C,MAAI,CAACD,OAAD,IAAY,CAACA,OAAO,CAACE,KAAzB,EAAgC;AAC9B,WAAO,KAAP;AACD;;AAED,aAAyDD,KAAK,IAAI,EAAlE;AAAA,MAAQE,UAAR,QAAQA,UAAR;AAAA,gCAAoBC,aAApB;AAAA,MAAoBA,aAApB,mCAAoC,CAApC;AAAA,MAAuCC,aAAvC,QAAuCA,aAAvC;;AACA,MAAMC,UAAU,GAAGN,OAAO,CAACE,KAAR,CAAcK,MAAd,IAAwB,CAA3C;;AAEA,MAAIJ,UAAU,KAAK,OAAnB,EAA4B;AAC1B,WAAO,CAAC,CAACG,UAAT;AACD;;AAED,MAAIA,UAAU,GAAGF,aAAb,IAA8BE,UAAU,GAAGD,aAA/C,EAA8D;AAC5D,WAAO,KAAP;AACD;;AAED,SAAO,IAAP;AACD,CAjBM;;;;IAmBcG,c;;;;;AACnB,4BAAc;AAAA;;AAAA;AACZ;AACA,UAAKC,MAAL,GAAc,IAAd;AACA,UAAKC,QAAL,GAAgB,IAAhB;AAEA,UAAKC,SAAL,GAAiB,0BACf,YAAM;AACJ,UAAI,MAAKF,MAAL,IAAe,MAAKC,QAAxB,EAAkC;AAChC,YAAIE,OAAO,gBAAGC,kBAAMC,aAAN,CAAoBC,gBAApB,EAA0B;AACtCd,UAAAA,KAAK,EAAE,MAAKQ,MAD0B;AAEtCT,UAAAA,OAAO,EAAE,MAAKU,QAFwB;AAGtCM,UAAAA,eAAe,EAAE,MAAKC,SAAL,CAAeC,IAAf,gDAHqB;AAItCC,UAAAA,mBAAmB,EAAE,MAAKA,mBAAL,CAAyBD,IAAzB;AAJiB,SAA1B,CAAd,CADgC,CAQhC;;;AACA,cAAKE,YAAL,CACE,YADF,EAEE,MAAKX,MAAL,CAAYN,UAAZ,KAA2B,OAA3B,GAAqC,0BAArC,GAAkE,kCAFpE;;AAIA,cAAKiB,YAAL,CAAkB,MAAlB,EAA0B,QAA1B;;AACA,cAAKC,gBAAL;;AAEAC,6BAASC,MAAT,CAAgBX,OAAhB,kDAA+B,YAAM;AACnCd,UAAAA,GAAG,CAAC,+BAAD,CAAH;AACA;AACD,SAHD;AAID,OApBD,MAoBO;AACLA,QAAAA,GAAG,CAAC,MAAD,CAAH;AACD;AACF,KAzBc,EA0Bf,EA1Be,EA2Bf;AAAE0B,MAAAA,OAAO,EAAE,KAAX;AAAkBC,MAAAA,QAAQ,EAAE;AAA5B,KA3Be,CAAjB;AA8BA,UAAKC,wBAAL,GAAgC,0BAAS,YAAM;AAC7C,YAAKC,aAAL,CAAmB,IAAIC,oCAAJ,CAAwB,MAAKC,OAAL,CAAaC,WAAb,EAAxB,EAAoD/B,UAAU,CAAC,MAAKW,QAAN,EAAgB,MAAKD,MAArB,CAA9D,CAAnB;AACD,KAF+B,CAAhC;AAIA,UAAKsB,iBAAL,GAAyB,0BACvB,YAAM;AACJ,YAAKJ,aAAL,CACE,IAAIK,8BAAJ,CACE,MAAKH,OAAL,CAAaC,WAAb,EADF,EAEE/B,UAAU,CAAC,MAAKW,QAAN,EAAgB,MAAKD,MAArB,CAFZ,EAGE,MAAKA,MAAL,KAAgBwB,SAHlB,CADF;AAOD,KATsB,EAUvB,EAVuB,EAWvB;AAAET,MAAAA,OAAO,EAAE,KAAX;AAAkBC,MAAAA,QAAQ,EAAE;AAA5B,KAXuB,CAAzB;AAvCY;AAoDb;;;;WAED,+BAAsB;AACpB,qCAAW,IAAX;AACD;;;WAED,4BAAmB;AACjB,UAAMS,QAAQ,GAAG,KAAKzB,MAAL,6BAAsB,KAAKA,MAAL,CAAYyB,QAAlC,IAA6C,KAAKzB,MAAL,CAAYyB,QAAzD,GAAoE,EAArF;AACA,UAAMC,IAAI,GAAGD,QAAQ,GAAGA,QAAQ,CAACE,KAAT,CAAe,CAAf,EAAkB,CAAlB,CAAH,GAA0B,IAA/C;AACA,WAAKhB,YAAL,CAAkB,MAAlB,EAA0Be,IAA1B;AACD;;;SAED,aAAUE,CAAV,EAAa;AACX,WAAK5B,MAAL,GAAc4B,CAAd;;AACA,WAAK1B,SAAL;;AACA,WAAKoB,iBAAL;AACD;;;SAED,eAAc;AACZ,aAAO,KAAKrB,QAAZ;AACD,K;SAED,aAAY2B,CAAZ,EAAe;AACb,WAAK3B,QAAL,GAAgB2B,CAAhB;;AACA,WAAK1B,SAAL,GAFa,CAGb;;;AACA,WAAKe,wBAAL;AACD;;;WAED,mBAAUY,IAAV,EAAgB;AACd,8CAAmB,KAAK5B,QAAxB,EAAkC,KAAKD,MAAL,CAAYN,UAA9C,EAA0DmC,IAA1D;;AACA,WAAKZ,wBAAL;;AACA,WAAKf,SAAL;AACD;;;WAED,6BAAoB;AAClB,WAAKA,SAAL;AACD;;;kDA1FyC4B,W","sourcesContent":["import Main from './main';\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport debounce from 'lodash/debounce';\nimport debug from 'debug';\nimport { ModelSetEvent, SessionChangedEvent } from '@pie-framework/pie-player-events';\nimport { renderMath } from '@pie-lib/pie-toolbox/math-rendering';\nimport { updateSessionValue } from './session-updater';\n\nconst log = debug('pie-ui:multiple-choice');\n\nexport const isComplete = (session, model) => {\n if (!session || !session.value) {\n return false;\n }\n\n const { choiceMode, minSelections = 1, maxSelections } = model || {};\n const selections = session.value.length || 0;\n\n if (choiceMode === 'radio') {\n return !!selections;\n }\n\n if (selections < minSelections || selections > maxSelections) {\n return false;\n }\n\n return true;\n};\n\nexport default class MultipleChoice extends HTMLElement {\n constructor() {\n super();\n this._model = null;\n this._session = null;\n\n this._rerender = debounce(\n () => {\n if (this._model && this._session) {\n var element = React.createElement(Main, {\n model: this._model,\n session: this._session,\n onChoiceChanged: this._onChange.bind(this),\n onShowCorrectToggle: this.onShowCorrectToggle.bind(this),\n });\n\n //TODO: aria-label is set in the _rerender because we need to change it when the model.choiceMode is updated. Consider revisiting the placement of the aria-label setting in the _rerender\n this.setAttribute(\n 'aria-label',\n this._model.choiceMode === 'radio' ? 'Multiple Choice Question' : 'Multiple Correct Answer Question',\n );\n this.setAttribute('role', 'region');\n this.setLangAttribute();\n\n ReactDOM.render(element, this, () => {\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 this._dispatchResponseChanged = debounce(() => {\n this.dispatchEvent(new SessionChangedEvent(this.tagName.toLowerCase(), isComplete(this._session, this._model)));\n });\n\n this._dispatchModelSet = debounce(\n () => {\n this.dispatchEvent(\n new ModelSetEvent(\n this.tagName.toLowerCase(),\n isComplete(this._session, this._model),\n this._model !== undefined,\n ),\n );\n },\n 50,\n { leading: false, trailing: true },\n );\n }\n\n onShowCorrectToggle() {\n renderMath(this);\n }\n\n setLangAttribute() {\n const language = this._model && typeof this._model.language ? this._model.language : '';\n const lang = language ? language.slice(0, 2) : 'en';\n this.setAttribute('lang', lang);\n }\n\n set model(s) {\n this._model = s;\n this._rerender();\n this._dispatchModelSet();\n }\n\n get session() {\n return this._session;\n }\n\n set session(s) {\n this._session = s;\n this._rerender();\n //TODO: remove this session-changed should only be emit on user change\n this._dispatchResponseChanged();\n }\n\n _onChange(data) {\n updateSessionValue(this._session, this._model.choiceMode, data);\n this._dispatchResponseChanged();\n this._rerender();\n }\n\n connectedCallback() {\n this._rerender();\n }\n}\n"],"file":"index.js"}
|
|
1
|
+
{"version":3,"sources":["../src/index.js"],"names":["log","isComplete","session","model","audioComplete","value","choiceMode","minSelections","maxSelections","selections","length","MultipleChoice","_model","_session","_rerender","element","React","createElement","Main","onChoiceChanged","_onChange","bind","onShowCorrectToggle","setAttribute","setLangAttribute","ReactDOM","render","leading","trailing","_dispatchResponseChanged","dispatchEvent","SessionChangedEvent","tagName","toLowerCase","_dispatchModelSet","ModelSetEvent","undefined","language","lang","slice","s","data","info","document","id","innerHTML","Object","assign","style","position","bottom","left","transform","backgroundColor","color","padding","borderRadius","boxShadow","zIndex","autoplayAudioEnabled","observer","MutationObserver","mutationsList","forEach","mutation","type","audio","querySelector","paused","_createAudioInfoToast","appendChild","enableAudio","play","removeChild","removeEventListener","addEventListener","handlePlaying","handleEnded","disconnect","observe","childList","subtree","HTMLElement"],"mappings":"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","sourcesContent":["import Main from './main';\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport debounce from 'lodash/debounce';\nimport debug from 'debug';\nimport { ModelSetEvent, SessionChangedEvent } from '@pie-framework/pie-player-events';\nimport { renderMath } from '@pie-lib/pie-toolbox/math-rendering';\nimport { updateSessionValue } from './session-updater';\n\nconst log = debug('pie-ui:multiple-choice');\n\nexport const isComplete = (session, model, audioComplete) => {\n if (!audioComplete) {\n return false;\n }\n\n if (!session || !session.value) {\n return false;\n }\n\n const { choiceMode, minSelections = 1, maxSelections } = model || {};\n const selections = session.value.length || 0;\n\n if (choiceMode === 'radio') {\n return !!selections;\n }\n\n if (selections < minSelections || selections > maxSelections) {\n return false;\n }\n\n return true;\n};\n\nexport default class MultipleChoice extends HTMLElement {\n constructor() {\n super();\n this._model = null;\n this._session = null;\n this.audioComplete = false;\n\n this._rerender = debounce(\n () => {\n if (this._model && this._session) {\n var element = React.createElement(Main, {\n model: this._model,\n session: this._session,\n onChoiceChanged: this._onChange.bind(this),\n onShowCorrectToggle: this.onShowCorrectToggle.bind(this),\n });\n\n //TODO: aria-label is set in the _rerender because we need to change it when the model.choiceMode is updated. Consider revisiting the placement of the aria-label setting in the _rerender\n this.setAttribute(\n 'aria-label',\n this._model.choiceMode === 'radio' ? 'Multiple Choice Question' : 'Multiple Correct Answer Question',\n );\n this.setAttribute('role', 'region');\n this.setLangAttribute();\n\n ReactDOM.render(element, this, () => {\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 this._dispatchResponseChanged = debounce(() => {\n this.dispatchEvent(new SessionChangedEvent(this.tagName.toLowerCase(), isComplete(this._session, this._model, this.audioComplete)));\n });\n\n this._dispatchModelSet = debounce(\n () => {\n this.dispatchEvent(\n new ModelSetEvent(\n this.tagName.toLowerCase(),\n isComplete(this._session, this._model),\n this._model !== undefined,\n ),\n );\n },\n 50,\n { leading: false, trailing: true },\n );\n }\n\n onShowCorrectToggle() {\n renderMath(this);\n }\n\n setLangAttribute() {\n const language = this._model && typeof this._model.language ? this._model.language : '';\n const lang = language ? language.slice(0, 2) : 'en';\n this.setAttribute('lang', lang);\n }\n\n set model(s) {\n this._model = s;\n this._rerender();\n this._dispatchModelSet();\n }\n\n get session() {\n return this._session;\n }\n\n set session(s) {\n this._session = s;\n this._rerender();\n //TODO: remove this session-changed should only be emit on user change\n this._dispatchResponseChanged();\n }\n\n _onChange(data) {\n updateSessionValue(this._session, this._model.choiceMode, data);\n this._dispatchResponseChanged();\n this._rerender();\n }\n\n _createAudioInfoToast() {\n const info = document.createElement('div');\n info.id = 'play-audio-info';\n info.innerHTML = 'Click anywhere to enable audio autoplay. Browser restrictions require user interaction to play audio.';\n Object.assign(info.style, {\n position: 'fixed',\n bottom: '20px',\n left: '50%',\n transform: 'translateX(-50%)',\n backgroundColor: '#333',\n color: '#fff',\n padding: '10px 20px',\n borderRadius: '5px',\n boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)',\n zIndex: '1000',\n });\n\n return info;\n }\n\n connectedCallback() {\n this._rerender();\n\n if (this._model && !this._model.autoplayAudioEnabled) {\n return;\n }\n\n const observer = new MutationObserver((mutationsList, observer) => {\n mutationsList.forEach((mutation) => {\n if (mutation.type === 'childList') {\n const audio = this.querySelector('audio[autoplay]');\n if (!audio) return;\n\n // if the audio is paused, it means the user has not interacted with the page yet and the audio will not play\n if (audio.paused && !this.querySelector('#play-audio-info')) {\n // add info message as a toast to enable audio playback\n const info = this._createAudioInfoToast();\n this.appendChild(info);\n\n const enableAudio = () => {\n audio.play();\n this.removeChild(info);\n document.removeEventListener('click', enableAudio);\n };\n\n document.addEventListener('click', enableAudio);\n }\n\n // we need to listen for the playing event to remove the toast in case the audio plays because of re-rendering\n const handlePlaying = () => {\n const info = this.querySelector('#play-audio-info');\n if (info) {\n this.removeChild(info);\n }\n audio.removeEventListener('playing', handlePlaying);\n };\n\n audio.addEventListener('playing', handlePlaying);\n\n // we need to listen for the ended event to update the isComplete state\n const handleEnded = () => {\n this.audioComplete = true;\n this._dispatchResponseChanged();\n audio.removeEventListener('ended', handleEnded);\n };\n\n audio.addEventListener('ended', handleEnded);\n\n observer.disconnect();\n }\n });\n });\n\n observer.observe(this, { childList: true, subtree: true });\n }\n}\n"],"file":"index.js"}
|
package/lib/multiple-choice.js
CHANGED
|
@@ -274,6 +274,7 @@ var MultipleChoice = /*#__PURE__*/function (_React$Component) {
|
|
|
274
274
|
isSelectionButtonBelow = _this$props3.isSelectionButtonBelow,
|
|
275
275
|
minSelections = _this$props3.minSelections,
|
|
276
276
|
maxSelections = _this$props3.maxSelections,
|
|
277
|
+
autoplayAudioEnabled = _this$props3.autoplayAudioEnabled,
|
|
277
278
|
session = _this$props3.session;
|
|
278
279
|
var _this$state = this.state,
|
|
279
280
|
showCorrect = _this$state.showCorrect,
|
|
@@ -309,7 +310,8 @@ var MultipleChoice = /*#__PURE__*/function (_React$Component) {
|
|
|
309
310
|
className: "prompt",
|
|
310
311
|
defaultClassName: "prompt",
|
|
311
312
|
prompt: prompt,
|
|
312
|
-
tagName: 'legend'
|
|
313
|
+
tagName: 'legend',
|
|
314
|
+
autoplayAudioEnabled: autoplayAudioEnabled
|
|
313
315
|
}), !alwaysShowCorrect && /*#__PURE__*/_react["default"].createElement(_correctAnswerToggle.CorrectAnswerToggle, {
|
|
314
316
|
show: showCorrectAnswerToggle,
|
|
315
317
|
toggled: showCorrect,
|
|
@@ -379,7 +381,8 @@ exports.MultipleChoice = MultipleChoice;
|
|
|
379
381
|
onShowCorrectToggle: _propTypes["default"].func,
|
|
380
382
|
isSelectionButtonBelow: _propTypes["default"].bool,
|
|
381
383
|
minSelections: _propTypes["default"].number,
|
|
382
|
-
maxSelections: _propTypes["default"].number
|
|
384
|
+
maxSelections: _propTypes["default"].number,
|
|
385
|
+
autoplayAudioEnabled: _propTypes["default"].bool
|
|
383
386
|
});
|
|
384
387
|
MultipleChoice.defaultProps = {
|
|
385
388
|
session: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/multiple-choice.jsx"],"names":["translator","Translator","styles","theme","main","color","text","backgroundColor","background","partLabel","display","fontSize","margin","fontWeight","paddingBottom","spacing","unit","teacherInstructions","marginBottom","horizontalLayout","flexDirection","flexWrap","gridLayout","fieldset","border","padding","minWidth","srOnly","position","left","top","width","height","overflow","errorText","typography","palette","error","paddingTop","MultipleChoice","props","event","target","value","checked","maxSelections","onChoiceChanged","session","length","setState","maxSelectionsErrorState","selected","mode","showCorrect","state","onShowCorrectToggle","choice","isCorrect","correct","isChecked","isSelected","undefined","alwaysShowCorrect","onToggle","bind","sessionValue","indexOf","nextProps","correctResponse","index","keyMode","String","fromCharCode","toUpperCase","choiceMode","classes","disabled","className","choices","gridColumns","prompt","responseCorrect","animationsDisabled","language","isSelectionButtonBelow","minSelections","isEvaluateMode","showCorrectAnswerToggle","columnsStyle","gridTemplateColumns","selections","teacherInstructionsDiv","renderHeading","hidden","visible","choicesLayout","map","selectedAnswerBackgroundColor","handleChange","hideTick","getChecked","getCorrectness","indexToSymbol","t","lng","React","Component","PropTypes","string","oneOf","array","object","bool","func","isRequired","number","defaultProps"],"mappings":"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","sourcesContent":["import React from 'react';\nimport PropTypes from 'prop-types';\nimport { CorrectAnswerToggle } from '@pie-lib/pie-toolbox/correct-answer-toggle';\nimport classNames from 'classnames';\nimport { withStyles } from '@material-ui/core/styles';\nimport { color, Collapsible, PreviewPrompt } from '@pie-lib/pie-toolbox/render-ui';\nimport Translator from '@pie-lib/pie-toolbox/translator';\n\nimport StyledChoice from './choice';\n\n// MultipleChoice\n\nconst { translator } = Translator;\n\nconst styles = (theme) => ({\n main: {\n color: color.text(),\n backgroundColor: color.background(),\n '& *': {\n '-webkit-font-smoothing': 'antialiased',\n },\n },\n partLabel: {\n display: 'block',\n fontSize: 'inherit',\n margin: '0',\n fontWeight: 'normal',\n paddingBottom: theme.spacing.unit * 2,\n },\n teacherInstructions: {\n marginBottom: theme.spacing.unit * 2,\n },\n horizontalLayout: {\n display: 'flex',\n flexDirection: 'row',\n flexWrap: 'wrap',\n },\n gridLayout: {\n display: 'grid',\n },\n fieldset: {\n border: '0px',\n padding: '0.01em 0 0 0',\n margin: '0px',\n minWidth: '0px',\n },\n srOnly: {\n position: 'absolute',\n left: '-10000px',\n top: 'auto',\n width: '1px',\n height: '1px',\n overflow: 'hidden',\n },\n errorText: {\n fontSize: theme.typography.fontSize - 2,\n color: theme.palette.error.main,\n paddingTop: theme.spacing.unit,\n },\n});\n\nexport class MultipleChoice extends React.Component {\n static propTypes = {\n className: PropTypes.string,\n mode: PropTypes.oneOf(['gather', 'view', 'evaluate']),\n choiceMode: PropTypes.oneOf(['radio', 'checkbox']),\n keyMode: PropTypes.oneOf(['numbers', 'letters', 'none']),\n choices: PropTypes.array,\n partLabel: PropTypes.string,\n prompt: PropTypes.string,\n teacherInstructions: PropTypes.string,\n session: PropTypes.object,\n disabled: PropTypes.bool,\n onChoiceChanged: PropTypes.func,\n responseCorrect: PropTypes.bool,\n classes: PropTypes.object.isRequired,\n correctResponse: PropTypes.array,\n choicesLayout: PropTypes.oneOf(['vertical', 'grid', 'horizontal']),\n gridColumns: PropTypes.string,\n alwaysShowCorrect: PropTypes.bool,\n animationsDisabled: PropTypes.bool,\n language: PropTypes.string,\n selectedAnswerBackgroundColor: PropTypes.string,\n onShowCorrectToggle: PropTypes.func,\n isSelectionButtonBelow: PropTypes.bool,\n minSelections: PropTypes.number,\n maxSelections: PropTypes.number,\n };\n\n constructor(props) {\n super(props);\n\n this.state = {\n showCorrect: this.props.alwaysShowCorrect || false,\n maxSelectionsErrorState: false,\n };\n\n this.onToggle = this.onToggle.bind(this);\n }\n\n isSelected(value) {\n const sessionValue = this.props.session && this.props.session.value;\n\n return sessionValue && sessionValue.indexOf && sessionValue.indexOf(value) >= 0;\n }\n\n // handleChange was added for accessibility. Please see comments and videos from PD-2441.\n handleChange = (event) => {\n const { value, checked } = event.target;\n const { maxSelections, onChoiceChanged, session } = this.props;\n\n if (session.value && session.value.length >= maxSelections) {\n // show/hide max selections error when user select/deselect an answer\n this.setState({ maxSelectionsErrorState: checked });\n\n if (checked) {\n // prevent selecting more answers\n return;\n }\n }\n\n onChoiceChanged({ value, selected: checked });\n };\n\n onToggle = () => {\n if (this.props.mode === 'evaluate') {\n this.setState({ showCorrect: !this.state.showCorrect }, () => {\n if (this.props.onShowCorrectToggle) {\n this.props.onShowCorrectToggle();\n }\n });\n }\n };\n\n UNSAFE_componentWillReceiveProps(nextProps) {\n if (!nextProps.correctResponse && this.state.showCorrect !== false) {\n this.setState({ showCorrect: false }, () => {\n if (this.props.onShowCorrectToggle) {\n this.props.onShowCorrectToggle();\n }\n });\n }\n\n if (nextProps.alwaysShowCorrect && this.state.showCorrect !== true) {\n this.setState({ showCorrect: true }, () => {\n if (this.props.onShowCorrectToggle) {\n this.props.onShowCorrectToggle();\n }\n });\n }\n }\n\n indexToSymbol(index) {\n if (this.props.keyMode === 'numbers') {\n return `${index + 1}`;\n }\n\n if (this.props.keyMode === 'letters') {\n return String.fromCharCode(97 + index).toUpperCase();\n }\n\n return '';\n }\n\n getCorrectness = (choice = {}) => {\n const isCorrect = choice.correct;\n const isChecked = this.isSelected(choice.value);\n\n if (this.state.showCorrect) {\n return isCorrect ? 'correct' : undefined;\n }\n\n if (isCorrect) {\n if (isChecked) {\n // A correct answer is selected: marked with a green checkmark\n return 'correct';\n } else {\n // A correct answer is NOT selected: marked with an orange X\n return 'incorrect';\n }\n } else {\n if (isChecked) {\n // An incorrect answer is selected: marked with an orange X\n return 'incorrect';\n } else {\n // An incorrect answer is NOT selected: not marked\n return undefined;\n }\n }\n };\n\n getChecked(choice) {\n if (this.state.showCorrect) {\n return choice.correct || false;\n }\n\n return this.isSelected(choice.value);\n }\n\n // renderHeading function was added for accessibility.\n renderHeading() {\n const { mode, choiceMode, classes } = this.props;\n\n if (mode !== 'gather') {\n return null;\n }\n\n return choiceMode === 'radio' ? (\n <h2 className={classes.srOnly}>Multiple Choice Question</h2>\n ) : (\n <h2 className={classes.srOnly}>Multiple Select Question</h2>\n );\n }\n\n render() {\n const {\n mode,\n disabled,\n className,\n choices = [],\n choiceMode,\n gridColumns,\n partLabel,\n prompt,\n responseCorrect,\n teacherInstructions,\n classes,\n alwaysShowCorrect,\n animationsDisabled,\n language,\n isSelectionButtonBelow,\n minSelections,\n maxSelections,\n session,\n } = this.props;\n const { showCorrect, maxSelectionsErrorState } = this.state;\n const isEvaluateMode = mode === 'evaluate';\n const showCorrectAnswerToggle = isEvaluateMode && !responseCorrect;\n const columnsStyle = gridColumns > 1 ? { gridTemplateColumns: `repeat(${gridColumns}, 1fr)` } : undefined;\n const selections = (session.value && session.value.length) || 0;\n\n const teacherInstructionsDiv = (\n <PreviewPrompt\n tagName=\"div\"\n className=\"prompt\"\n defaultClassName=\"teacher-instructions\"\n prompt={teacherInstructions}\n />\n );\n\n return (\n <div className={classNames(classes.main, className, 'multiple-choice')}>\n {partLabel && <h3 className={classes.partLabel}>{partLabel}</h3>}\n\n {this.renderHeading()}\n\n {teacherInstructions && (\n <div className={classes.teacherInstructions}>\n {!animationsDisabled ? (\n <Collapsible\n labels={{\n hidden: 'Show Teacher Instructions',\n visible: 'Hide Teacher Instructions',\n }}\n >\n {teacherInstructionsDiv}\n </Collapsible>\n ) : (\n teacherInstructionsDiv\n )}\n </div>\n )}\n\n <fieldset className={classes.fieldset}>\n <PreviewPrompt className=\"prompt\" defaultClassName=\"prompt\" prompt={prompt} tagName={'legend'} />\n\n {!alwaysShowCorrect && (\n <CorrectAnswerToggle\n show={showCorrectAnswerToggle}\n toggled={showCorrect}\n onToggle={this.onToggle.bind(this)}\n language={language}\n />\n )}\n\n <div\n className={classNames({\n [classes.gridLayout]: this.props.choicesLayout === 'grid',\n [classes.horizontalLayout]: this.props.choicesLayout === 'horizontal',\n })}\n style={columnsStyle}\n >\n {choices.map((choice, index) => (\n <StyledChoice\n choicesLayout={this.props.choicesLayout}\n selectedAnswerBackgroundColor={this.props.selectedAnswerBackgroundColor}\n gridColumns={gridColumns}\n key={`choice-${index}`}\n choice={choice}\n index={index}\n choicesLength={choices.length}\n showCorrect={showCorrect}\n isEvaluateMode={isEvaluateMode}\n choiceMode={choiceMode}\n disabled={disabled}\n onChoiceChanged={this.handleChange}\n hideTick={choice.hideTick}\n checked={this.getChecked(choice)}\n correctness={isEvaluateMode ? this.getCorrectness(choice) : undefined}\n displayKey={this.indexToSymbol(index)}\n isSelectionButtonBelow={isSelectionButtonBelow}\n />\n ))}\n </div>\n </fieldset>\n\n {choiceMode === 'checkbox' && selections < minSelections && (\n <div className={classes.errorText}>\n {translator.t(`translation:multipleChoice:minSelections_${minSelections === 1 ? 'one' : 'other'}`, {\n lng: language,\n minSelections,\n })}\n </div>\n )}\n {choiceMode === 'checkbox' && maxSelectionsErrorState && (\n <div className={classes.errorText}>\n {translator.t(`translation:multipleChoice:maxSelections_${maxSelections === 1 ? 'one' : 'other'}`, {\n lng: language,\n maxSelections,\n })}\n </div>\n )}\n </div>\n );\n }\n}\n\nMultipleChoice.defaultProps = {\n session: {\n value: [],\n },\n};\n\nexport default withStyles(styles)(MultipleChoice);\n"],"file":"multiple-choice.js"}
|
|
1
|
+
{"version":3,"sources":["../src/multiple-choice.jsx"],"names":["translator","Translator","styles","theme","main","color","text","backgroundColor","background","partLabel","display","fontSize","margin","fontWeight","paddingBottom","spacing","unit","teacherInstructions","marginBottom","horizontalLayout","flexDirection","flexWrap","gridLayout","fieldset","border","padding","minWidth","srOnly","position","left","top","width","height","overflow","errorText","typography","palette","error","paddingTop","MultipleChoice","props","event","target","value","checked","maxSelections","onChoiceChanged","session","length","setState","maxSelectionsErrorState","selected","mode","showCorrect","state","onShowCorrectToggle","choice","isCorrect","correct","isChecked","isSelected","undefined","alwaysShowCorrect","onToggle","bind","sessionValue","indexOf","nextProps","correctResponse","index","keyMode","String","fromCharCode","toUpperCase","choiceMode","classes","disabled","className","choices","gridColumns","prompt","responseCorrect","animationsDisabled","language","isSelectionButtonBelow","minSelections","autoplayAudioEnabled","isEvaluateMode","showCorrectAnswerToggle","columnsStyle","gridTemplateColumns","selections","teacherInstructionsDiv","renderHeading","hidden","visible","choicesLayout","map","selectedAnswerBackgroundColor","handleChange","hideTick","getChecked","getCorrectness","indexToSymbol","t","lng","React","Component","PropTypes","string","oneOf","array","object","bool","func","isRequired","number","defaultProps"],"mappings":"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","sourcesContent":["import React from 'react';\nimport PropTypes from 'prop-types';\nimport { CorrectAnswerToggle } from '@pie-lib/pie-toolbox/correct-answer-toggle';\nimport classNames from 'classnames';\nimport { withStyles } from '@material-ui/core/styles';\nimport { color, Collapsible, PreviewPrompt } from '@pie-lib/pie-toolbox/render-ui';\nimport Translator from '@pie-lib/pie-toolbox/translator';\n\nimport StyledChoice from './choice';\n\n// MultipleChoice\n\nconst { translator } = Translator;\n\nconst styles = (theme) => ({\n main: {\n color: color.text(),\n backgroundColor: color.background(),\n '& *': {\n '-webkit-font-smoothing': 'antialiased',\n },\n },\n partLabel: {\n display: 'block',\n fontSize: 'inherit',\n margin: '0',\n fontWeight: 'normal',\n paddingBottom: theme.spacing.unit * 2,\n },\n teacherInstructions: {\n marginBottom: theme.spacing.unit * 2,\n },\n horizontalLayout: {\n display: 'flex',\n flexDirection: 'row',\n flexWrap: 'wrap',\n },\n gridLayout: {\n display: 'grid',\n },\n fieldset: {\n border: '0px',\n padding: '0.01em 0 0 0',\n margin: '0px',\n minWidth: '0px',\n },\n srOnly: {\n position: 'absolute',\n left: '-10000px',\n top: 'auto',\n width: '1px',\n height: '1px',\n overflow: 'hidden',\n },\n errorText: {\n fontSize: theme.typography.fontSize - 2,\n color: theme.palette.error.main,\n paddingTop: theme.spacing.unit,\n },\n});\n\nexport class MultipleChoice extends React.Component {\n static propTypes = {\n className: PropTypes.string,\n mode: PropTypes.oneOf(['gather', 'view', 'evaluate']),\n choiceMode: PropTypes.oneOf(['radio', 'checkbox']),\n keyMode: PropTypes.oneOf(['numbers', 'letters', 'none']),\n choices: PropTypes.array,\n partLabel: PropTypes.string,\n prompt: PropTypes.string,\n teacherInstructions: PropTypes.string,\n session: PropTypes.object,\n disabled: PropTypes.bool,\n onChoiceChanged: PropTypes.func,\n responseCorrect: PropTypes.bool,\n classes: PropTypes.object.isRequired,\n correctResponse: PropTypes.array,\n choicesLayout: PropTypes.oneOf(['vertical', 'grid', 'horizontal']),\n gridColumns: PropTypes.string,\n alwaysShowCorrect: PropTypes.bool,\n animationsDisabled: PropTypes.bool,\n language: PropTypes.string,\n selectedAnswerBackgroundColor: PropTypes.string,\n onShowCorrectToggle: PropTypes.func,\n isSelectionButtonBelow: PropTypes.bool,\n minSelections: PropTypes.number,\n maxSelections: PropTypes.number,\n autoplayAudioEnabled: PropTypes.bool,\n };\n\n constructor(props) {\n super(props);\n\n this.state = {\n showCorrect: this.props.alwaysShowCorrect || false,\n maxSelectionsErrorState: false,\n };\n\n this.onToggle = this.onToggle.bind(this);\n }\n\n isSelected(value) {\n const sessionValue = this.props.session && this.props.session.value;\n\n return sessionValue && sessionValue.indexOf && sessionValue.indexOf(value) >= 0;\n }\n\n // handleChange was added for accessibility. Please see comments and videos from PD-2441.\n handleChange = (event) => {\n const { value, checked } = event.target;\n const { maxSelections, onChoiceChanged, session } = this.props;\n\n if (session.value && session.value.length >= maxSelections) {\n // show/hide max selections error when user select/deselect an answer\n this.setState({ maxSelectionsErrorState: checked });\n\n if (checked) {\n // prevent selecting more answers\n return;\n }\n }\n\n onChoiceChanged({ value, selected: checked });\n };\n\n onToggle = () => {\n if (this.props.mode === 'evaluate') {\n this.setState({ showCorrect: !this.state.showCorrect }, () => {\n if (this.props.onShowCorrectToggle) {\n this.props.onShowCorrectToggle();\n }\n });\n }\n };\n\n UNSAFE_componentWillReceiveProps(nextProps) {\n if (!nextProps.correctResponse && this.state.showCorrect !== false) {\n this.setState({ showCorrect: false }, () => {\n if (this.props.onShowCorrectToggle) {\n this.props.onShowCorrectToggle();\n }\n });\n }\n\n if (nextProps.alwaysShowCorrect && this.state.showCorrect !== true) {\n this.setState({ showCorrect: true }, () => {\n if (this.props.onShowCorrectToggle) {\n this.props.onShowCorrectToggle();\n }\n });\n }\n }\n\n indexToSymbol(index) {\n if (this.props.keyMode === 'numbers') {\n return `${index + 1}`;\n }\n\n if (this.props.keyMode === 'letters') {\n return String.fromCharCode(97 + index).toUpperCase();\n }\n\n return '';\n }\n\n getCorrectness = (choice = {}) => {\n const isCorrect = choice.correct;\n const isChecked = this.isSelected(choice.value);\n\n if (this.state.showCorrect) {\n return isCorrect ? 'correct' : undefined;\n }\n\n if (isCorrect) {\n if (isChecked) {\n // A correct answer is selected: marked with a green checkmark\n return 'correct';\n } else {\n // A correct answer is NOT selected: marked with an orange X\n return 'incorrect';\n }\n } else {\n if (isChecked) {\n // An incorrect answer is selected: marked with an orange X\n return 'incorrect';\n } else {\n // An incorrect answer is NOT selected: not marked\n return undefined;\n }\n }\n };\n\n getChecked(choice) {\n if (this.state.showCorrect) {\n return choice.correct || false;\n }\n\n return this.isSelected(choice.value);\n }\n\n // renderHeading function was added for accessibility.\n renderHeading() {\n const { mode, choiceMode, classes } = this.props;\n\n if (mode !== 'gather') {\n return null;\n }\n\n return choiceMode === 'radio' ? (\n <h2 className={classes.srOnly}>Multiple Choice Question</h2>\n ) : (\n <h2 className={classes.srOnly}>Multiple Select Question</h2>\n );\n }\n\n render() {\n const {\n mode,\n disabled,\n className,\n choices = [],\n choiceMode,\n gridColumns,\n partLabel,\n prompt,\n responseCorrect,\n teacherInstructions,\n classes,\n alwaysShowCorrect,\n animationsDisabled,\n language,\n isSelectionButtonBelow,\n minSelections,\n maxSelections,\n autoplayAudioEnabled,\n session,\n } = this.props;\n const { showCorrect, maxSelectionsErrorState } = this.state;\n const isEvaluateMode = mode === 'evaluate';\n const showCorrectAnswerToggle = isEvaluateMode && !responseCorrect;\n const columnsStyle = gridColumns > 1 ? { gridTemplateColumns: `repeat(${gridColumns}, 1fr)` } : undefined;\n const selections = (session.value && session.value.length) || 0;\n\n const teacherInstructionsDiv = (\n <PreviewPrompt\n tagName=\"div\"\n className=\"prompt\"\n defaultClassName=\"teacher-instructions\"\n prompt={teacherInstructions}\n />\n );\n\n return (\n <div className={classNames(classes.main, className, 'multiple-choice')}>\n {partLabel && <h3 className={classes.partLabel}>{partLabel}</h3>}\n\n {this.renderHeading()}\n\n {teacherInstructions && (\n <div className={classes.teacherInstructions}>\n {!animationsDisabled ? (\n <Collapsible\n labels={{\n hidden: 'Show Teacher Instructions',\n visible: 'Hide Teacher Instructions',\n }}\n >\n {teacherInstructionsDiv}\n </Collapsible>\n ) : (\n teacherInstructionsDiv\n )}\n </div>\n )}\n\n <fieldset className={classes.fieldset}>\n <PreviewPrompt\n className=\"prompt\"\n defaultClassName=\"prompt\"\n prompt={prompt}\n tagName={'legend'}\n autoplayAudioEnabled={autoplayAudioEnabled}\n />\n\n {!alwaysShowCorrect && (\n <CorrectAnswerToggle\n show={showCorrectAnswerToggle}\n toggled={showCorrect}\n onToggle={this.onToggle.bind(this)}\n language={language}\n />\n )}\n\n <div\n className={classNames({\n [classes.gridLayout]: this.props.choicesLayout === 'grid',\n [classes.horizontalLayout]: this.props.choicesLayout === 'horizontal',\n })}\n style={columnsStyle}\n >\n {choices.map((choice, index) => (\n <StyledChoice\n choicesLayout={this.props.choicesLayout}\n selectedAnswerBackgroundColor={this.props.selectedAnswerBackgroundColor}\n gridColumns={gridColumns}\n key={`choice-${index}`}\n choice={choice}\n index={index}\n choicesLength={choices.length}\n showCorrect={showCorrect}\n isEvaluateMode={isEvaluateMode}\n choiceMode={choiceMode}\n disabled={disabled}\n onChoiceChanged={this.handleChange}\n hideTick={choice.hideTick}\n checked={this.getChecked(choice)}\n correctness={isEvaluateMode ? this.getCorrectness(choice) : undefined}\n displayKey={this.indexToSymbol(index)}\n isSelectionButtonBelow={isSelectionButtonBelow}\n />\n ))}\n </div>\n </fieldset>\n\n {choiceMode === 'checkbox' && selections < minSelections && (\n <div className={classes.errorText}>\n {translator.t(`translation:multipleChoice:minSelections_${minSelections === 1 ? 'one' : 'other'}`, {\n lng: language,\n minSelections,\n })}\n </div>\n )}\n {choiceMode === 'checkbox' && maxSelectionsErrorState && (\n <div className={classes.errorText}>\n {translator.t(`translation:multipleChoice:maxSelections_${maxSelections === 1 ? 'one' : 'other'}`, {\n lng: language,\n maxSelections,\n })}\n </div>\n )}\n </div>\n );\n }\n}\n\nMultipleChoice.defaultProps = {\n session: {\n value: [],\n },\n};\n\nexport default withStyles(styles)(MultipleChoice);\n"],"file":"multiple-choice.js"}
|
package/module/configure.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {_dll_react, _dll_prop_types, _dll_react_dom, _dll_classnames, _dll_lodash, _dll_debug} from "../../../@pie-lib/pie-toolbox-math-rendering-module@3.1.1/module/index.js";
|
|
2
|
-
import {_dll_pie_lib__pie_toolbox_editable_html, _dll_pie_lib__pie_toolbox_config_ui, _dll_pie_lib__pie_toolbox_render_ui} from "../../../@pie-lib/pie-toolbox-module@5.8.
|
|
2
|
+
import {_dll_pie_lib__pie_toolbox_editable_html, _dll_pie_lib__pie_toolbox_config_ui, _dll_pie_lib__pie_toolbox_render_ui} from "../../../@pie-lib/pie-toolbox-module@5.8.1/module/index.js";
|
|
3
3
|
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
|
4
4
|
function getDefaultExportFromCjs(x) {
|
|
5
5
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
package/module/controller.js
CHANGED
|
@@ -20704,6 +20704,7 @@ async function model(question, session, env, updateSession) {
|
|
|
20704
20704
|
selectedAnswerBackgroundColor: normalizedQuestion.selectedAnswerBackgroundColor || 'initial',
|
|
20705
20705
|
minSelections: normalizedQuestion.minSelections,
|
|
20706
20706
|
maxSelections: normalizedQuestion.maxSelections,
|
|
20707
|
+
autoplayAudioEnabled: normalizedQuestion.autoplayAudioEnabled,
|
|
20707
20708
|
};
|
|
20708
20709
|
|
|
20709
20710
|
const { role, mode } = env || {};
|
package/module/element.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {_dll_react, _dll_prop_types, _dll_classnames, _dll_react_dom, _dll_lodash, _dll_debug, _dll_pie_lib__pie_toolbox_math_rendering} from "../../../@pie-lib/pie-toolbox-math-rendering-module@3.1.1/module/index.js";
|
|
2
|
-
import {_dll_pie_lib__pie_toolbox_render_ui, _dll_pie_lib__pie_toolbox_correct_answer_toggle} from "../../../@pie-lib/pie-toolbox-module@5.8.
|
|
2
|
+
import {_dll_pie_lib__pie_toolbox_render_ui, _dll_pie_lib__pie_toolbox_correct_answer_toggle} from "../../../@pie-lib/pie-toolbox-module@5.8.1/module/index.js";
|
|
3
3
|
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
|
4
4
|
function getDefaultExportFromCjs(x) {
|
|
5
5
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
|
@@ -12657,7 +12657,8 @@ class MultipleChoice$1 extends React$2.Component {
|
|
|
12657
12657
|
onShowCorrectToggle: PropTypes$1.func,
|
|
12658
12658
|
isSelectionButtonBelow: PropTypes$1.bool,
|
|
12659
12659
|
minSelections: PropTypes$1.number,
|
|
12660
|
-
maxSelections: PropTypes$1.number
|
|
12660
|
+
maxSelections: PropTypes$1.number,
|
|
12661
|
+
autoplayAudioEnabled: PropTypes$1.bool
|
|
12661
12662
|
};
|
|
12662
12663
|
}
|
|
12663
12664
|
constructor(props) {
|
|
@@ -12773,19 +12774,19 @@ class MultipleChoice$1 extends React$2.Component {
|
|
|
12773
12774
|
__self: this,
|
|
12774
12775
|
__source: {
|
|
12775
12776
|
fileName: _jsxFileName$1,
|
|
12776
|
-
lineNumber:
|
|
12777
|
+
lineNumber: 210
|
|
12777
12778
|
}
|
|
12778
12779
|
}, "Multiple Choice Question") : React$2.createElement('h2', {
|
|
12779
12780
|
className: classes.srOnly,
|
|
12780
12781
|
__self: this,
|
|
12781
12782
|
__source: {
|
|
12782
12783
|
fileName: _jsxFileName$1,
|
|
12783
|
-
lineNumber:
|
|
12784
|
+
lineNumber: 212
|
|
12784
12785
|
}
|
|
12785
12786
|
}, "Multiple Select Question");
|
|
12786
12787
|
}
|
|
12787
12788
|
render() {
|
|
12788
|
-
const {mode, disabled, className, choices = [], choiceMode, gridColumns, partLabel, prompt, responseCorrect, teacherInstructions, classes, alwaysShowCorrect, animationsDisabled, language, isSelectionButtonBelow, minSelections, maxSelections, session} = this.props;
|
|
12789
|
+
const {mode, disabled, className, choices = [], choiceMode, gridColumns, partLabel, prompt, responseCorrect, teacherInstructions, classes, alwaysShowCorrect, animationsDisabled, language, isSelectionButtonBelow, minSelections, maxSelections, autoplayAudioEnabled, session} = this.props;
|
|
12789
12790
|
const {showCorrect, maxSelectionsErrorState} = this.state;
|
|
12790
12791
|
const isEvaluateMode = mode === 'evaluate';
|
|
12791
12792
|
const showCorrectAnswerToggle = isEvaluateMode && !responseCorrect;
|
|
@@ -12801,7 +12802,7 @@ class MultipleChoice$1 extends React$2.Component {
|
|
|
12801
12802
|
__self: this,
|
|
12802
12803
|
__source: {
|
|
12803
12804
|
fileName: _jsxFileName$1,
|
|
12804
|
-
lineNumber:
|
|
12805
|
+
lineNumber: 245
|
|
12805
12806
|
}
|
|
12806
12807
|
});
|
|
12807
12808
|
return React$2.createElement('div', {
|
|
@@ -12809,21 +12810,21 @@ class MultipleChoice$1 extends React$2.Component {
|
|
|
12809
12810
|
__self: this,
|
|
12810
12811
|
__source: {
|
|
12811
12812
|
fileName: _jsxFileName$1,
|
|
12812
|
-
lineNumber:
|
|
12813
|
+
lineNumber: 254
|
|
12813
12814
|
}
|
|
12814
12815
|
}, partLabel && React$2.createElement('h3', {
|
|
12815
12816
|
className: classes.partLabel,
|
|
12816
12817
|
__self: this,
|
|
12817
12818
|
__source: {
|
|
12818
12819
|
fileName: _jsxFileName$1,
|
|
12819
|
-
lineNumber:
|
|
12820
|
+
lineNumber: 255
|
|
12820
12821
|
}
|
|
12821
12822
|
}, partLabel), this.renderHeading(), teacherInstructions && React$2.createElement('div', {
|
|
12822
12823
|
className: classes.teacherInstructions,
|
|
12823
12824
|
__self: this,
|
|
12824
12825
|
__source: {
|
|
12825
12826
|
fileName: _jsxFileName$1,
|
|
12826
|
-
lineNumber:
|
|
12827
|
+
lineNumber: 260
|
|
12827
12828
|
}
|
|
12828
12829
|
}, !animationsDisabled ? React$2.createElement(Collapsible, {
|
|
12829
12830
|
labels: {
|
|
@@ -12833,24 +12834,25 @@ class MultipleChoice$1 extends React$2.Component {
|
|
|
12833
12834
|
__self: this,
|
|
12834
12835
|
__source: {
|
|
12835
12836
|
fileName: _jsxFileName$1,
|
|
12836
|
-
lineNumber:
|
|
12837
|
+
lineNumber: 262
|
|
12837
12838
|
}
|
|
12838
12839
|
}, teacherInstructionsDiv) : teacherInstructionsDiv), React$2.createElement('fieldset', {
|
|
12839
12840
|
className: classes.fieldset,
|
|
12840
12841
|
__self: this,
|
|
12841
12842
|
__source: {
|
|
12842
12843
|
fileName: _jsxFileName$1,
|
|
12843
|
-
lineNumber:
|
|
12844
|
+
lineNumber: 276
|
|
12844
12845
|
}
|
|
12845
12846
|
}, React$2.createElement(PreviewPrompt, {
|
|
12846
12847
|
className: "prompt",
|
|
12847
12848
|
defaultClassName: "prompt",
|
|
12848
12849
|
prompt: prompt,
|
|
12849
12850
|
tagName: 'legend',
|
|
12851
|
+
autoplayAudioEnabled: autoplayAudioEnabled,
|
|
12850
12852
|
__self: this,
|
|
12851
12853
|
__source: {
|
|
12852
12854
|
fileName: _jsxFileName$1,
|
|
12853
|
-
lineNumber:
|
|
12855
|
+
lineNumber: 277
|
|
12854
12856
|
}
|
|
12855
12857
|
}), !alwaysShowCorrect && React$2.createElement(CorrectAnswerToggle, {
|
|
12856
12858
|
show: showCorrectAnswerToggle,
|
|
@@ -12860,7 +12862,7 @@ class MultipleChoice$1 extends React$2.Component {
|
|
|
12860
12862
|
__self: this,
|
|
12861
12863
|
__source: {
|
|
12862
12864
|
fileName: _jsxFileName$1,
|
|
12863
|
-
lineNumber:
|
|
12865
|
+
lineNumber: 286
|
|
12864
12866
|
}
|
|
12865
12867
|
}), React$2.createElement('div', {
|
|
12866
12868
|
className: classNames({
|
|
@@ -12871,7 +12873,7 @@ class MultipleChoice$1 extends React$2.Component {
|
|
|
12871
12873
|
__self: this,
|
|
12872
12874
|
__source: {
|
|
12873
12875
|
fileName: _jsxFileName$1,
|
|
12874
|
-
lineNumber:
|
|
12876
|
+
lineNumber: 294
|
|
12875
12877
|
}
|
|
12876
12878
|
}, choices.map((choice, index) => React$2.createElement(StyledChoice, {
|
|
12877
12879
|
choicesLayout: this.props.choicesLayout,
|
|
@@ -12894,14 +12896,14 @@ class MultipleChoice$1 extends React$2.Component {
|
|
|
12894
12896
|
__self: this,
|
|
12895
12897
|
__source: {
|
|
12896
12898
|
fileName: _jsxFileName$1,
|
|
12897
|
-
lineNumber:
|
|
12899
|
+
lineNumber: 302
|
|
12898
12900
|
}
|
|
12899
12901
|
})))), choiceMode === 'checkbox' && selections < minSelections && React$2.createElement('div', {
|
|
12900
12902
|
className: classes.errorText,
|
|
12901
12903
|
__self: this,
|
|
12902
12904
|
__source: {
|
|
12903
12905
|
fileName: _jsxFileName$1,
|
|
12904
|
-
lineNumber:
|
|
12906
|
+
lineNumber: 326
|
|
12905
12907
|
}
|
|
12906
12908
|
}, translator.t(`translation:multipleChoice:minSelections_${minSelections === 1 ? 'one' : 'other'}`, {
|
|
12907
12909
|
lng: language,
|
|
@@ -12911,7 +12913,7 @@ class MultipleChoice$1 extends React$2.Component {
|
|
|
12911
12913
|
__self: this,
|
|
12912
12914
|
__source: {
|
|
12913
12915
|
fileName: _jsxFileName$1,
|
|
12914
|
-
lineNumber:
|
|
12916
|
+
lineNumber: 334
|
|
12915
12917
|
}
|
|
12916
12918
|
}, translator.t(`translation:multipleChoice:maxSelections_${maxSelections === 1 ? 'one' : 'other'}`, {
|
|
12917
12919
|
lng: language,
|
|
@@ -13066,7 +13068,10 @@ const {debounce: debounce} = _dll_lodash;
|
|
|
13066
13068
|
const debug = _dll_debug;
|
|
13067
13069
|
const {renderMath: renderMath} = _dll_pie_lib__pie_toolbox_math_rendering;
|
|
13068
13070
|
const log = debug('pie-ui:multiple-choice');
|
|
13069
|
-
const isComplete = (session, model) => {
|
|
13071
|
+
const isComplete = (session, model, audioComplete) => {
|
|
13072
|
+
if (!audioComplete) {
|
|
13073
|
+
return false;
|
|
13074
|
+
}
|
|
13070
13075
|
if (!session || !session.value) {
|
|
13071
13076
|
return false;
|
|
13072
13077
|
}
|
|
@@ -13085,6 +13090,7 @@ class MultipleChoice extends HTMLElement {
|
|
|
13085
13090
|
super();
|
|
13086
13091
|
this._model = null;
|
|
13087
13092
|
this._session = null;
|
|
13093
|
+
this.audioComplete = false;
|
|
13088
13094
|
this._rerender = debounce(() => {
|
|
13089
13095
|
if (this._model && this._session) {
|
|
13090
13096
|
var element = React.createElement(Root, {
|
|
@@ -13108,7 +13114,7 @@ class MultipleChoice extends HTMLElement {
|
|
|
13108
13114
|
trailing: true
|
|
13109
13115
|
});
|
|
13110
13116
|
this._dispatchResponseChanged = debounce(() => {
|
|
13111
|
-
this.dispatchEvent(new SessionChangedEvent_1(this.tagName.toLowerCase(), isComplete(this._session, this._model)));
|
|
13117
|
+
this.dispatchEvent(new SessionChangedEvent_1(this.tagName.toLowerCase(), isComplete(this._session, this._model, this.audioComplete)));
|
|
13112
13118
|
});
|
|
13113
13119
|
this._dispatchModelSet = debounce(() => {
|
|
13114
13120
|
this.dispatchEvent(new ModelSetEvent_1(this.tagName.toLowerCase(), isComplete(this._session, this._model), this._model !== undefined));
|
|
@@ -13143,8 +13149,66 @@ class MultipleChoice extends HTMLElement {
|
|
|
13143
13149
|
this._dispatchResponseChanged();
|
|
13144
13150
|
this._rerender();
|
|
13145
13151
|
}
|
|
13152
|
+
_createAudioInfoToast() {
|
|
13153
|
+
const info = document.createElement('div');
|
|
13154
|
+
info.id = 'play-audio-info';
|
|
13155
|
+
info.innerHTML = 'Click anywhere to enable audio autoplay. Browser restrictions require user interaction to play audio.';
|
|
13156
|
+
Object.assign(info.style, {
|
|
13157
|
+
position: 'fixed',
|
|
13158
|
+
bottom: '20px',
|
|
13159
|
+
left: '50%',
|
|
13160
|
+
transform: 'translateX(-50%)',
|
|
13161
|
+
backgroundColor: '#333',
|
|
13162
|
+
color: '#fff',
|
|
13163
|
+
padding: '10px 20px',
|
|
13164
|
+
borderRadius: '5px',
|
|
13165
|
+
boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)',
|
|
13166
|
+
zIndex: '1000'
|
|
13167
|
+
});
|
|
13168
|
+
return info;
|
|
13169
|
+
}
|
|
13146
13170
|
connectedCallback() {
|
|
13147
13171
|
this._rerender();
|
|
13172
|
+
if (this._model && !this._model.autoplayAudioEnabled) {
|
|
13173
|
+
return;
|
|
13174
|
+
}
|
|
13175
|
+
const observer = new MutationObserver((mutationsList, observer) => {
|
|
13176
|
+
mutationsList.forEach(mutation => {
|
|
13177
|
+
if (mutation.type === 'childList') {
|
|
13178
|
+
const audio = this.querySelector('audio[autoplay]');
|
|
13179
|
+
if (!audio) return;
|
|
13180
|
+
if (audio.paused && !this.querySelector('#play-audio-info')) {
|
|
13181
|
+
const info = this._createAudioInfoToast();
|
|
13182
|
+
this.appendChild(info);
|
|
13183
|
+
const enableAudio = () => {
|
|
13184
|
+
audio.play();
|
|
13185
|
+
this.removeChild(info);
|
|
13186
|
+
document.removeEventListener('click', enableAudio);
|
|
13187
|
+
};
|
|
13188
|
+
document.addEventListener('click', enableAudio);
|
|
13189
|
+
}
|
|
13190
|
+
const handlePlaying = () => {
|
|
13191
|
+
const info = this.querySelector('#play-audio-info');
|
|
13192
|
+
if (info) {
|
|
13193
|
+
this.removeChild(info);
|
|
13194
|
+
}
|
|
13195
|
+
audio.removeEventListener('playing', handlePlaying);
|
|
13196
|
+
};
|
|
13197
|
+
audio.addEventListener('playing', handlePlaying);
|
|
13198
|
+
const handleEnded = () => {
|
|
13199
|
+
this.audioComplete = true;
|
|
13200
|
+
this._dispatchResponseChanged();
|
|
13201
|
+
audio.removeEventListener('ended', handleEnded);
|
|
13202
|
+
};
|
|
13203
|
+
audio.addEventListener('ended', handleEnded);
|
|
13204
|
+
observer.disconnect();
|
|
13205
|
+
}
|
|
13206
|
+
});
|
|
13207
|
+
});
|
|
13208
|
+
observer.observe(this, {
|
|
13209
|
+
childList: true,
|
|
13210
|
+
subtree: true
|
|
13211
|
+
});
|
|
13148
13212
|
}
|
|
13149
13213
|
}
|
|
13150
13214
|
export {MultipleChoice as default, isComplete};
|
package/module/manifest.json
CHANGED
package/module/print.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {_dll_react, _dll_prop_types, _dll_classnames, _dll_react_dom, _dll_lodash, _dll_pie_lib__pie_toolbox_math_rendering, _dll_debug} from "../../../@pie-lib/pie-toolbox-math-rendering-module@3.1.1/module/index.js";
|
|
2
|
-
import {_dll_pie_lib__pie_toolbox_render_ui, _dll_pie_lib__pie_toolbox_correct_answer_toggle} from "../../../@pie-lib/pie-toolbox-module@5.8.
|
|
2
|
+
import {_dll_pie_lib__pie_toolbox_render_ui, _dll_pie_lib__pie_toolbox_correct_answer_toggle} from "../../../@pie-lib/pie-toolbox-module@5.8.1/module/index.js";
|
|
3
3
|
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
|
4
4
|
function getDefaultExportFromCjs(x) {
|
|
5
5
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
|
@@ -12657,7 +12657,8 @@ class MultipleChoice extends React$2.Component {
|
|
|
12657
12657
|
onShowCorrectToggle: PropTypes$1.func,
|
|
12658
12658
|
isSelectionButtonBelow: PropTypes$1.bool,
|
|
12659
12659
|
minSelections: PropTypes$1.number,
|
|
12660
|
-
maxSelections: PropTypes$1.number
|
|
12660
|
+
maxSelections: PropTypes$1.number,
|
|
12661
|
+
autoplayAudioEnabled: PropTypes$1.bool
|
|
12661
12662
|
};
|
|
12662
12663
|
}
|
|
12663
12664
|
constructor(props) {
|
|
@@ -12773,19 +12774,19 @@ class MultipleChoice extends React$2.Component {
|
|
|
12773
12774
|
__self: this,
|
|
12774
12775
|
__source: {
|
|
12775
12776
|
fileName: _jsxFileName$1,
|
|
12776
|
-
lineNumber:
|
|
12777
|
+
lineNumber: 210
|
|
12777
12778
|
}
|
|
12778
12779
|
}, "Multiple Choice Question") : React$2.createElement('h2', {
|
|
12779
12780
|
className: classes.srOnly,
|
|
12780
12781
|
__self: this,
|
|
12781
12782
|
__source: {
|
|
12782
12783
|
fileName: _jsxFileName$1,
|
|
12783
|
-
lineNumber:
|
|
12784
|
+
lineNumber: 212
|
|
12784
12785
|
}
|
|
12785
12786
|
}, "Multiple Select Question");
|
|
12786
12787
|
}
|
|
12787
12788
|
render() {
|
|
12788
|
-
const {mode, disabled, className, choices = [], choiceMode, gridColumns, partLabel, prompt, responseCorrect, teacherInstructions, classes, alwaysShowCorrect, animationsDisabled, language, isSelectionButtonBelow, minSelections, maxSelections, session} = this.props;
|
|
12789
|
+
const {mode, disabled, className, choices = [], choiceMode, gridColumns, partLabel, prompt, responseCorrect, teacherInstructions, classes, alwaysShowCorrect, animationsDisabled, language, isSelectionButtonBelow, minSelections, maxSelections, autoplayAudioEnabled, session} = this.props;
|
|
12789
12790
|
const {showCorrect, maxSelectionsErrorState} = this.state;
|
|
12790
12791
|
const isEvaluateMode = mode === 'evaluate';
|
|
12791
12792
|
const showCorrectAnswerToggle = isEvaluateMode && !responseCorrect;
|
|
@@ -12801,7 +12802,7 @@ class MultipleChoice extends React$2.Component {
|
|
|
12801
12802
|
__self: this,
|
|
12802
12803
|
__source: {
|
|
12803
12804
|
fileName: _jsxFileName$1,
|
|
12804
|
-
lineNumber:
|
|
12805
|
+
lineNumber: 245
|
|
12805
12806
|
}
|
|
12806
12807
|
});
|
|
12807
12808
|
return React$2.createElement('div', {
|
|
@@ -12809,21 +12810,21 @@ class MultipleChoice extends React$2.Component {
|
|
|
12809
12810
|
__self: this,
|
|
12810
12811
|
__source: {
|
|
12811
12812
|
fileName: _jsxFileName$1,
|
|
12812
|
-
lineNumber:
|
|
12813
|
+
lineNumber: 254
|
|
12813
12814
|
}
|
|
12814
12815
|
}, partLabel && React$2.createElement('h3', {
|
|
12815
12816
|
className: classes.partLabel,
|
|
12816
12817
|
__self: this,
|
|
12817
12818
|
__source: {
|
|
12818
12819
|
fileName: _jsxFileName$1,
|
|
12819
|
-
lineNumber:
|
|
12820
|
+
lineNumber: 255
|
|
12820
12821
|
}
|
|
12821
12822
|
}, partLabel), this.renderHeading(), teacherInstructions && React$2.createElement('div', {
|
|
12822
12823
|
className: classes.teacherInstructions,
|
|
12823
12824
|
__self: this,
|
|
12824
12825
|
__source: {
|
|
12825
12826
|
fileName: _jsxFileName$1,
|
|
12826
|
-
lineNumber:
|
|
12827
|
+
lineNumber: 260
|
|
12827
12828
|
}
|
|
12828
12829
|
}, !animationsDisabled ? React$2.createElement(Collapsible, {
|
|
12829
12830
|
labels: {
|
|
@@ -12833,24 +12834,25 @@ class MultipleChoice extends React$2.Component {
|
|
|
12833
12834
|
__self: this,
|
|
12834
12835
|
__source: {
|
|
12835
12836
|
fileName: _jsxFileName$1,
|
|
12836
|
-
lineNumber:
|
|
12837
|
+
lineNumber: 262
|
|
12837
12838
|
}
|
|
12838
12839
|
}, teacherInstructionsDiv) : teacherInstructionsDiv), React$2.createElement('fieldset', {
|
|
12839
12840
|
className: classes.fieldset,
|
|
12840
12841
|
__self: this,
|
|
12841
12842
|
__source: {
|
|
12842
12843
|
fileName: _jsxFileName$1,
|
|
12843
|
-
lineNumber:
|
|
12844
|
+
lineNumber: 276
|
|
12844
12845
|
}
|
|
12845
12846
|
}, React$2.createElement(PreviewPrompt, {
|
|
12846
12847
|
className: "prompt",
|
|
12847
12848
|
defaultClassName: "prompt",
|
|
12848
12849
|
prompt: prompt,
|
|
12849
12850
|
tagName: 'legend',
|
|
12851
|
+
autoplayAudioEnabled: autoplayAudioEnabled,
|
|
12850
12852
|
__self: this,
|
|
12851
12853
|
__source: {
|
|
12852
12854
|
fileName: _jsxFileName$1,
|
|
12853
|
-
lineNumber:
|
|
12855
|
+
lineNumber: 277
|
|
12854
12856
|
}
|
|
12855
12857
|
}), !alwaysShowCorrect && React$2.createElement(CorrectAnswerToggle, {
|
|
12856
12858
|
show: showCorrectAnswerToggle,
|
|
@@ -12860,7 +12862,7 @@ class MultipleChoice extends React$2.Component {
|
|
|
12860
12862
|
__self: this,
|
|
12861
12863
|
__source: {
|
|
12862
12864
|
fileName: _jsxFileName$1,
|
|
12863
|
-
lineNumber:
|
|
12865
|
+
lineNumber: 286
|
|
12864
12866
|
}
|
|
12865
12867
|
}), React$2.createElement('div', {
|
|
12866
12868
|
className: classNames({
|
|
@@ -12871,7 +12873,7 @@ class MultipleChoice extends React$2.Component {
|
|
|
12871
12873
|
__self: this,
|
|
12872
12874
|
__source: {
|
|
12873
12875
|
fileName: _jsxFileName$1,
|
|
12874
|
-
lineNumber:
|
|
12876
|
+
lineNumber: 294
|
|
12875
12877
|
}
|
|
12876
12878
|
}, choices.map((choice, index) => React$2.createElement(StyledChoice, {
|
|
12877
12879
|
choicesLayout: this.props.choicesLayout,
|
|
@@ -12894,14 +12896,14 @@ class MultipleChoice extends React$2.Component {
|
|
|
12894
12896
|
__self: this,
|
|
12895
12897
|
__source: {
|
|
12896
12898
|
fileName: _jsxFileName$1,
|
|
12897
|
-
lineNumber:
|
|
12899
|
+
lineNumber: 302
|
|
12898
12900
|
}
|
|
12899
12901
|
})))), choiceMode === 'checkbox' && selections < minSelections && React$2.createElement('div', {
|
|
12900
12902
|
className: classes.errorText,
|
|
12901
12903
|
__self: this,
|
|
12902
12904
|
__source: {
|
|
12903
12905
|
fileName: _jsxFileName$1,
|
|
12904
|
-
lineNumber:
|
|
12906
|
+
lineNumber: 326
|
|
12905
12907
|
}
|
|
12906
12908
|
}, translator.t(`translation:multipleChoice:minSelections_${minSelections === 1 ? 'one' : 'other'}`, {
|
|
12907
12909
|
lng: language,
|
|
@@ -12911,7 +12913,7 @@ class MultipleChoice extends React$2.Component {
|
|
|
12911
12913
|
__self: this,
|
|
12912
12914
|
__source: {
|
|
12913
12915
|
fileName: _jsxFileName$1,
|
|
12914
|
-
lineNumber:
|
|
12916
|
+
lineNumber: 334
|
|
12915
12917
|
}
|
|
12916
12918
|
}, translator.t(`translation:multipleChoice:maxSelections_${maxSelections === 1 ? 'one' : 'other'}`, {
|
|
12917
12919
|
lng: language,
|
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pie-element/multiple-choice",
|
|
3
3
|
"repository": "pie-framework/pie-elements",
|
|
4
|
-
"version": "9.7.4-next.
|
|
4
|
+
"version": "9.7.4-next.9+3caa0b4db",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
8
8
|
"dependencies": {
|
|
9
9
|
"@material-ui/core": "^3.9.2",
|
|
10
10
|
"@pie-framework/pie-player-events": "^0.1.0",
|
|
11
|
-
"@pie-lib/pie-toolbox": "2.
|
|
11
|
+
"@pie-lib/pie-toolbox": "2.8.0",
|
|
12
12
|
"classnames": "^2.2.5",
|
|
13
13
|
"debug": "^4.1.1",
|
|
14
14
|
"enzyme-to-json": "^3.3.3",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"react-test-renderer": "^16.3.2",
|
|
20
20
|
"react-transition-group": "^2.3.1"
|
|
21
21
|
},
|
|
22
|
-
"gitHead": "
|
|
22
|
+
"gitHead": "3caa0b4db682d6e62243f5fced08f82b790db854",
|
|
23
23
|
"scripts": {
|
|
24
24
|
"postpublish": "../../scripts/postpublish"
|
|
25
25
|
},
|