@pie-element/image-cloze-association 10.3.0 → 10.3.1-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -46
- package/configure/CHANGELOG.md +25 -38
- package/configure/package.json +3 -3
- package/controller/CHANGELOG.md +38 -6
- package/controller/package.json +1 -1
- package/lib/image-container.js +3 -12
- package/lib/image-container.js.map +1 -1
- package/lib/image-drop-target.js +6 -46
- package/lib/image-drop-target.js.map +1 -1
- package/lib/index.js +2 -2
- package/lib/index.js.map +1 -1
- package/lib/possible-response.js +5 -36
- package/lib/possible-response.js.map +1 -1
- package/lib/possible-responses.js +19 -39
- package/lib/possible-responses.js.map +1 -1
- package/lib/root.js +6 -120
- package/lib/root.js.map +1 -1
- package/package.json +5 -5
- package/src/__tests__/root.test.jsx +2 -261
- package/src/image-container.jsx +0 -9
- package/src/image-drop-target.jsx +1 -44
- package/src/index.js +2 -2
- package/src/possible-response.jsx +1 -45
- package/src/possible-responses.jsx +16 -37
- package/src/root.jsx +2 -117
- package/lib/keyboard-coordinates.js +0 -111
- package/lib/keyboard-coordinates.js.map +0 -1
- package/src/__tests__/image-drop-target.test.jsx +0 -169
- package/src/__tests__/keyboard-coordinates.test.js +0 -127
- package/src/__tests__/possible-response.test.jsx +0 -113
- package/src/__tests__/possible-responses.test.jsx +0 -63
- package/src/keyboard-coordinates.js +0 -115
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["_react","_interopRequireDefault","require","_client","_mathRendering","_renderUi","_piePlayerEvents","_root","ImageClozeAssociation","HTMLElement","constructor","model","m","_model","dispatchEvent","ModelSetEvent","tagName","toLowerCase","isComplete","_render","autoplayAudioEnabled","completeAudioEnabled","completeResponses","duplicateResponses","hasUnplacedChoices","maxResponsePerZone","responseAreasToBeFilled","elementContext","audioComplete","audio","querySelector","isInsidePrompt","closest","_session","answers","Array","isArray","filledResponseAreas","Map","map","item","containerIndex","values","length","areResponseAreasFilled","allAnswersValue","answer","value","requiredAnswersPlaced","some","response","every","val","includes","session","s","updateAnswer","data","selector","SessionChangedEvent","_createAudioInfoToast","info","document","createElement","id","Object","assign","style","position","top","width","height","display","justifyContent","alignItems","background","zIndex","cursor","img","src","EnableAudioAutoplayImage","alt","appendChild","connectedCallback","observer","MutationObserver","mutationsList","forEach","mutation","type","container","enableAudio","play","removeChild","removeEventListener","setTimeout","paused","addEventListener","handlePlaying","handleEnded","_audio","_handlePlaying","_handleEnded","_enableAudio","disconnect","observe","childList","subtree","disconnectedCallback","unmount","el","React","ImageClozeAssociationComponent","bind","createRoot","render","queueMicrotask","renderMath","exports","default"],"sources":["../src/index.js"],"sourcesContent":["import React from 'react';\nimport { createRoot } from 'react-dom/client';\nimport { renderMath } from '@pie-lib/math-rendering';\nimport { EnableAudioAutoplayImage } from '@pie-lib/render-ui';\nimport { ModelSetEvent, SessionChangedEvent } from '@pie-framework/pie-player-events';\n\nimport ImageClozeAssociationComponent from './root';\n\nexport default class ImageClozeAssociation extends HTMLElement {\n constructor() {\n super();\n this._root = null;\n }\n\n set model(m) {\n this._model = m;\n\n this.dispatchEvent(new ModelSetEvent(this.tagName.toLowerCase(), this.isComplete(), !!this._model));\n this._render();\n }\n\n isComplete() {\n const {\n autoplayAudioEnabled,\n completeAudioEnabled,\n completeResponses,\n duplicateResponses,\n hasUnplacedChoices,\n maxResponsePerZone,\n responseAreasToBeFilled,\n } = this._model || {};\n const elementContext = this;\n\n // check audio completion if audio settings are enabled and audio actually exists\n if (autoplayAudioEnabled && completeAudioEnabled && !this.audioComplete) {\n if (elementContext) {\n const audio = elementContext.querySelector('audio');\n const isInsidePrompt = audio && audio.closest('.preview-prompt');\n\n // only require audio completion if audio exists and is inside the prompt\n if (audio && isInsidePrompt) {\n return false;\n }\n }\n }\n\n if (!this._session || !this._session.answers) {\n return false;\n }\n\n const { answers } = this._session;\n\n if (!Array.isArray(answers)) {\n return false;\n }\n\n // filter answers by containerIndex and count the ones with content\n const filledResponseAreas = [...new Map(answers.map((item) => [item.containerIndex, item])).values()].length;\n // check if an answer choice was added to at least as many response areas\n // as the number of populated response areas in the correct answer\n const areResponseAreasFilled = filledResponseAreas >= responseAreasToBeFilled;\n\n if (maxResponsePerZone > 1) {\n if (duplicateResponses) {\n // an answer choice can be used multiple times\n return areResponseAreasFilled;\n }\n\n // any correct answer have any unplaced answer choices (by the author)\n if (hasUnplacedChoices) {\n return areResponseAreasFilled;\n }\n\n const allAnswersValue = answers.map((answer) => answer.value);\n\n // check if any correct answer have any unplaced answer choices (by the student)\n const requiredAnswersPlaced = completeResponses.some((response) =>\n response.every((val) => allAnswersValue.includes(val)),\n );\n\n // true - all choices (required for a correct response) were placed into a response area\n return requiredAnswersPlaced;\n }\n\n return areResponseAreasFilled;\n }\n\n set session(s) {\n if (s && !s.answers) {\n s.answers = [];\n }\n\n this._session = s;\n this._render();\n }\n\n get session() {\n return this._session;\n }\n\n updateAnswer(data) {\n this._session.answers = data;\n this._session.selector = 'Mouse';\n\n this.dispatchEvent(new SessionChangedEvent(this.tagName.toLowerCase(), this.isComplete()));\n\n this._render();\n }\n\n _createAudioInfoToast() {\n const info = document.createElement('div');\n info.id = 'play-audio-info';\n\n Object.assign(info.style, {\n position: 'absolute',\n top: 0,\n width: '100%',\n height: '100%',\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n background: 'white',\n zIndex: '1000',\n cursor: 'pointer',\n });\n\n const img = document.createElement('img');\n img.src = EnableAudioAutoplayImage;\n img.alt = 'Click anywhere to enable audio autoplay';\n img.width = 500;\n img.height = 300;\n\n info.appendChild(img);\n return info;\n }\n\n connectedCallback() {\n this._render();\n\n // Observation: audio in Chrome will have the autoplay attribute,\n // while other browsers will not have the autoplay attribute and will need a user interaction to play the audio\n // This workaround fixes the issue of audio being cached and played on any user interaction in Safari and Firefox\n const observer = new MutationObserver((mutationsList, observer) => {\n mutationsList.forEach((mutation) => {\n if (mutation.type === 'childList') {\n const audio = this.querySelector('audio');\n const isInsidePrompt = audio && audio.closest('.preview-prompt');\n\n if (!this._model) return;\n if (!this._model.autoplayAudioEnabled) return;\n if (audio && !isInsidePrompt) return;\n if (!audio) return;\n\n const info = this._createAudioInfoToast();\n const container = this.querySelector('#main-container');\n const enableAudio = () => {\n if (this.querySelector('#play-audio-info')) {\n audio.play();\n container.removeChild(info);\n }\n\n document.removeEventListener('click', enableAudio);\n };\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 // FIX FOR SAFARI: play with a slight delay to check if autoplay was blocked\n setTimeout(() => {\n if (audio.paused && !this.querySelector('#play-audio-info')) {\n // add info message as a toast to enable audio playback\n container.appendChild(info);\n document.addEventListener('click', enableAudio);\n } else {\n document.removeEventListener('click', enableAudio);\n }\n }, 500);\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\n if (info) {\n container.removeChild(info);\n }\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.dispatchEvent(new SessionChangedEvent(this.tagName.toLowerCase(), this.isComplete()));\n\n audio.removeEventListener('ended', handleEnded);\n };\n\n audio.addEventListener('ended', handleEnded);\n\n // store references to remove later\n this._audio = audio;\n this._handlePlaying = handlePlaying;\n this._handleEnded = handleEnded;\n this._enableAudio = enableAudio;\n\n observer.disconnect();\n }\n });\n });\n\n observer.observe(this, { childList: true, subtree: true });\n }\n\n disconnectedCallback() {\n document.removeEventListener('click', this._enableAudio);\n\n if (this._audio) {\n this._audio.removeEventListener('playing', this._handlePlaying);\n this._audio.removeEventListener('ended', this._handleEnded);\n this._audio = null;\n }\n\n if (this._root) {\n this._root.unmount();\n this._root = null;\n }\n }\n\n _render() {\n if (this._model && this._session) {\n const el = React.createElement(ImageClozeAssociationComponent, {\n model: this._model,\n session: this._session,\n updateAnswer: this.updateAnswer.bind(this),\n });\n\n if (!this._root) {\n this._root = createRoot(this);\n }\n this._root.render(el);\n queueMicrotask(() => {\n renderMath(this);\n });\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"index.js","names":["_react","_interopRequireDefault","require","_client","_mathRendering","_renderUi","_piePlayerEvents","_root","ImageClozeAssociation","HTMLElement","constructor","model","m","_model","dispatchEvent","ModelSetEvent","tagName","toLowerCase","isComplete","_render","autoplayAudioEnabled","completeAudioEnabled","completeResponses","duplicateResponses","hasUnplacedChoices","maxResponsePerZone","responseAreasToBeFilled","elementContext","audioComplete","audio","querySelector","isInsidePrompt","closest","_session","answers","Array","isArray","filledResponseAreas","Map","map","item","containerIndex","values","length","areResponseAreasFilled","allAnswersValue","answer","value","requiredAnswersPlaced","some","response","every","val","includes","session","s","updateAnswer","data","selector","SessionChangedEvent","_createAudioInfoToast","info","document","createElement","id","Object","assign","style","position","top","width","height","display","justifyContent","alignItems","background","zIndex","cursor","img","src","EnableAudioAutoplayImage","alt","appendChild","connectedCallback","observer","MutationObserver","mutationsList","forEach","mutation","type","container","enableAudio","play","removeChild","removeEventListener","setTimeout","paused","addEventListener","handlePlaying","handleEnded","_audio","_handlePlaying","_handleEnded","_enableAudio","disconnect","observe","childList","subtree","disconnectedCallback","unmount","el","React","ImageClozeAssociationComponent","bind","createRoot","render","queueMicrotask","renderMath","exports","default"],"sources":["../src/index.js"],"sourcesContent":["import React from 'react';\nimport { createRoot } from 'react-dom/client';\nimport { renderMath } from '@pie-lib/math-rendering';\nimport { EnableAudioAutoplayImage } from '@pie-lib/render-ui';\nimport { ModelSetEvent, SessionChangedEvent } from '@pie-framework/pie-player-events';\n\nimport ImageClozeAssociationComponent from './root';\n\nexport default class ImageClozeAssociation extends HTMLElement {\n constructor() {\n super();\n this._root = null;\n }\n\n set model(m) {\n this._model = m;\n\n this.dispatchEvent(new ModelSetEvent(this.tagName.toLowerCase(), this.isComplete(), !!this._model));\n this._render();\n }\n\n isComplete() {\n const {\n autoplayAudioEnabled,\n completeAudioEnabled,\n completeResponses,\n duplicateResponses,\n hasUnplacedChoices,\n maxResponsePerZone,\n responseAreasToBeFilled,\n } = this._model || {};\n const elementContext = this;\n\n // check audio completion if audio settings are enabled and audio actually exists\n if (autoplayAudioEnabled && completeAudioEnabled && !this.audioComplete) {\n if (elementContext) {\n const audio = elementContext.querySelector('audio');\n const isInsidePrompt = audio && audio.closest('#preview-prompt');\n\n // only require audio completion if audio exists and is inside the prompt\n if (audio && isInsidePrompt) {\n return false;\n }\n }\n }\n\n if (!this._session || !this._session.answers) {\n return false;\n }\n\n const { answers } = this._session;\n\n if (!Array.isArray(answers)) {\n return false;\n }\n\n // filter answers by containerIndex and count the ones with content\n const filledResponseAreas = [...new Map(answers.map((item) => [item.containerIndex, item])).values()].length;\n // check if an answer choice was added to at least as many response areas\n // as the number of populated response areas in the correct answer\n const areResponseAreasFilled = filledResponseAreas >= responseAreasToBeFilled;\n\n if (maxResponsePerZone > 1) {\n if (duplicateResponses) {\n // an answer choice can be used multiple times\n return areResponseAreasFilled;\n }\n\n // any correct answer have any unplaced answer choices (by the author)\n if (hasUnplacedChoices) {\n return areResponseAreasFilled;\n }\n\n const allAnswersValue = answers.map((answer) => answer.value);\n\n // check if any correct answer have any unplaced answer choices (by the student)\n const requiredAnswersPlaced = completeResponses.some((response) =>\n response.every((val) => allAnswersValue.includes(val)),\n );\n\n // true - all choices (required for a correct response) were placed into a response area\n return requiredAnswersPlaced;\n }\n\n return areResponseAreasFilled;\n }\n\n set session(s) {\n if (s && !s.answers) {\n s.answers = [];\n }\n\n this._session = s;\n this._render();\n }\n\n get session() {\n return this._session;\n }\n\n updateAnswer(data) {\n this._session.answers = data;\n this._session.selector = 'Mouse';\n\n this.dispatchEvent(new SessionChangedEvent(this.tagName.toLowerCase(), this.isComplete()));\n\n this._render();\n }\n\n _createAudioInfoToast() {\n const info = document.createElement('div');\n info.id = 'play-audio-info';\n\n Object.assign(info.style, {\n position: 'absolute',\n top: 0,\n width: '100%',\n height: '100%',\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n background: 'white',\n zIndex: '1000',\n cursor: 'pointer',\n });\n\n const img = document.createElement('img');\n img.src = EnableAudioAutoplayImage;\n img.alt = 'Click anywhere to enable audio autoplay';\n img.width = 500;\n img.height = 300;\n\n info.appendChild(img);\n return info;\n }\n\n connectedCallback() {\n this._render();\n\n // Observation: audio in Chrome will have the autoplay attribute,\n // while other browsers will not have the autoplay attribute and will need a user interaction to play the audio\n // This workaround fixes the issue of audio being cached and played on any user interaction in Safari and Firefox\n const observer = new MutationObserver((mutationsList, observer) => {\n mutationsList.forEach((mutation) => {\n if (mutation.type === 'childList') {\n const audio = this.querySelector('audio');\n const isInsidePrompt = audio && audio.closest('#preview-prompt');\n\n if (!this._model) return;\n if (!this._model.autoplayAudioEnabled) return;\n if (audio && !isInsidePrompt) return;\n if (!audio) return;\n\n const info = this._createAudioInfoToast();\n const container = this.querySelector('#main-container');\n const enableAudio = () => {\n if (this.querySelector('#play-audio-info')) {\n audio.play();\n container.removeChild(info);\n }\n\n document.removeEventListener('click', enableAudio);\n };\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 // FIX FOR SAFARI: play with a slight delay to check if autoplay was blocked\n setTimeout(() => {\n if (audio.paused && !this.querySelector('#play-audio-info')) {\n // add info message as a toast to enable audio playback\n container.appendChild(info);\n document.addEventListener('click', enableAudio);\n } else {\n document.removeEventListener('click', enableAudio);\n }\n }, 500);\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\n if (info) {\n container.removeChild(info);\n }\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.dispatchEvent(new SessionChangedEvent(this.tagName.toLowerCase(), this.isComplete()));\n\n audio.removeEventListener('ended', handleEnded);\n };\n\n audio.addEventListener('ended', handleEnded);\n\n // store references to remove later\n this._audio = audio;\n this._handlePlaying = handlePlaying;\n this._handleEnded = handleEnded;\n this._enableAudio = enableAudio;\n\n observer.disconnect();\n }\n });\n });\n\n observer.observe(this, { childList: true, subtree: true });\n }\n\n disconnectedCallback() {\n document.removeEventListener('click', this._enableAudio);\n\n if (this._audio) {\n this._audio.removeEventListener('playing', this._handlePlaying);\n this._audio.removeEventListener('ended', this._handleEnded);\n this._audio = null;\n }\n\n if (this._root) {\n this._root.unmount();\n this._root = null;\n }\n }\n\n _render() {\n if (this._model && this._session) {\n const el = React.createElement(ImageClozeAssociationComponent, {\n model: this._model,\n session: this._session,\n updateAnswer: this.updateAnswer.bind(this),\n });\n\n if (!this._root) {\n this._root = createRoot(this);\n }\n this._root.render(el);\n queueMicrotask(() => {\n renderMath(this);\n });\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
package/lib/possible-response.js
CHANGED
|
@@ -46,9 +46,6 @@ const BaseContainer = (0, _styles.styled)('div')(() => ({
|
|
|
46
46
|
},
|
|
47
47
|
'&.baseIncorrect': {
|
|
48
48
|
border: `2px solid ${_renderUi.color.incorrect()} !important`
|
|
49
|
-
},
|
|
50
|
-
'&.selected': {
|
|
51
|
-
opacity: 0.7
|
|
52
49
|
}
|
|
53
50
|
}));
|
|
54
51
|
const StyledSpan = (0, _styles.styled)(_staticHtmlSpan.default)(() => ({
|
|
@@ -64,10 +61,7 @@ const PossibleResponse = ({
|
|
|
64
61
|
data,
|
|
65
62
|
onDragBegin,
|
|
66
63
|
answerChoiceTransparency,
|
|
67
|
-
isOverlay
|
|
68
|
-
selectedResponse,
|
|
69
|
-
onSelectClick,
|
|
70
|
-
onPlacementClick
|
|
64
|
+
isOverlay
|
|
71
65
|
}) => {
|
|
72
66
|
const rootRef = (0, _react.useRef)(null);
|
|
73
67
|
const longPressTimer = (0, _react.useRef)(null);
|
|
@@ -85,25 +79,6 @@ const PossibleResponse = ({
|
|
|
85
79
|
},
|
|
86
80
|
disabled: !canDrag
|
|
87
81
|
});
|
|
88
|
-
const isSelected = !!selectedResponse && selectedResponse.id === data.id && selectedResponse.containerIndex === data.containerIndex;
|
|
89
|
-
const handleClick = e => {
|
|
90
|
-
if (!canDrag) return;
|
|
91
|
-
e.stopPropagation();
|
|
92
|
-
const isPlaced = data.containerIndex !== undefined;
|
|
93
|
-
if (isSelected) {
|
|
94
|
-
// Clicking the already-selected tile again deselects it.
|
|
95
|
-
onSelectClick?.(data);
|
|
96
|
-
} else if (selectedResponse && isPlaced) {
|
|
97
|
-
// Something else is selected, and this tile is already inside a container:
|
|
98
|
-
// place the selection into that same container (a swap/insert, handled by the
|
|
99
|
-
// existing handleOnAnswerSelect logic).
|
|
100
|
-
onPlacementClick?.(data.containerIndex);
|
|
101
|
-
} else {
|
|
102
|
-
// Nothing selected yet, or this is a pool item (pool items are never placement
|
|
103
|
-
// targets — the pool itself, in possible-responses.jsx, is): select this tile.
|
|
104
|
-
onSelectClick?.(data);
|
|
105
|
-
}
|
|
106
|
-
};
|
|
107
82
|
const handleTouchEnd = () => {
|
|
108
83
|
clearTimeout(longPressTimer.current);
|
|
109
84
|
};
|
|
@@ -149,8 +124,7 @@ const PossibleResponse = ({
|
|
|
149
124
|
const containerClassNames = (0, _classnames.default)({
|
|
150
125
|
answerChoiceTransparency: answerChoiceTransparency && !isDragging,
|
|
151
126
|
[correctnessClass]: !!correctnessClass,
|
|
152
|
-
textAnswerChoiceStyle: !containsImage && !isOverlay
|
|
153
|
-
selected: isSelected && !isDragging
|
|
127
|
+
textAnswerChoiceStyle: !containsImage && !isOverlay
|
|
154
128
|
});
|
|
155
129
|
const promptClassNames = (0, _classnames.default)({
|
|
156
130
|
hiddenSpan: data.hidden
|
|
@@ -161,8 +135,7 @@ const PossibleResponse = ({
|
|
|
161
135
|
ref: ref => {
|
|
162
136
|
rootRef.current = ref;
|
|
163
137
|
setNodeRef(ref);
|
|
164
|
-
}
|
|
165
|
-
onClick: handleClick
|
|
138
|
+
}
|
|
166
139
|
}, listeners, attributes), /*#__PURE__*/_react.default.createElement(StyledSpan, {
|
|
167
140
|
html: data.value,
|
|
168
141
|
className: promptClassNames
|
|
@@ -177,16 +150,12 @@ PossibleResponse.propTypes = {
|
|
|
177
150
|
data: _propTypes.default.object.isRequired,
|
|
178
151
|
onDragBegin: _propTypes.default.func.isRequired,
|
|
179
152
|
answerChoiceTransparency: _propTypes.default.bool,
|
|
180
|
-
isOverlay: _propTypes.default.bool
|
|
181
|
-
selectedResponse: _propTypes.default.object,
|
|
182
|
-
onSelectClick: _propTypes.default.func,
|
|
183
|
-
onPlacementClick: _propTypes.default.func
|
|
153
|
+
isOverlay: _propTypes.default.bool
|
|
184
154
|
};
|
|
185
155
|
PossibleResponse.defaultProps = {
|
|
186
156
|
containerStyle: {},
|
|
187
157
|
answerChoiceTransparency: false,
|
|
188
|
-
isOverlay: false
|
|
189
|
-
selectedResponse: null
|
|
158
|
+
isOverlay: false
|
|
190
159
|
};
|
|
191
160
|
var _default = exports.default = PossibleResponse;
|
|
192
161
|
//# sourceMappingURL=possible-response.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"possible-response.js","names":["_react","_interopRequireWildcard","require","_propTypes","_interopRequireDefault","_classnames","_styles","_core","_renderUi","_evaluationIcon","_staticHtmlSpan","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","BaseContainer","styled","position","backgroundColor","color","white","border","borderDark","display","alignItems","justifyContent","minHeight","width","pointerEvents","padding","margin","transparent","correct","incorrect","opacity","StyledSpan","StaticHTMLSpan","cursor","background","visibility","PossibleResponse","canDrag","containerStyle","data","onDragBegin","answerChoiceTransparency","isOverlay","selectedResponse","onSelectClick","onPlacementClick","rootRef","useRef","longPressTimer","setNodeRef","attributes","listeners","isDragging","useDraggable","id","value","containerIndex","disabled","isSelected","handleClick","stopPropagation","isPlaced","undefined","handleTouchEnd","clearTimeout","current","handleTouchMove","handleTouchStart","preventDefault","setTimeout","useEffect","node","addEventListener","passive","removeEventListener","isCorrect","evaluationStyle","fontSize","bottom","right","correctnessClass","imgRegex","containsImage","test","containerClassNames","classNames","textAnswerChoiceStyle","selected","promptClassNames","hiddenSpan","hidden","createElement","_extends2","className","style","ref","onClick","html","propTypes","PropTypes","bool","isRequired","object","func","defaultProps","_default","exports"],"sources":["../src/possible-response.jsx"],"sourcesContent":["import React, { useEffect, useRef } from 'react';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\nimport { styled } from '@mui/material/styles';\nimport { useDraggable } from '@dnd-kit/core';\nimport { color } from '@pie-lib/render-ui';\n\nimport EvaluationIcon from './evaluation-icon';\nimport StaticHTMLSpan from './static-html-span';\n\nconst BaseContainer = styled('div')(() => ({\n position: 'relative',\n backgroundColor: color.white(),\n border: `1px solid ${color.borderDark()}`,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n minHeight: '28px',\n width: 'fit-content',\n '& span img': {\n // Added for touch devices, for image content.\n // This will prevent the context menu from appearing and not allowing other interactions with the image.\n // If interactions with the image in the token will be requested we should handle only the context Menu.\n pointerEvents: 'none',\n },\n '&.textAnswerChoiceStyle': {\n padding: '0 10px',\n margin: '4px 6px !important',\n },\n '&.answerChoiceTransparency': {\n border: 'none',\n backgroundColor: `${color.transparent()}`,\n '&:hover': {\n border: `1px solid ${color.borderDark()}`,\n },\n },\n '&.baseCorrect': {\n border: `2px solid ${color.correct()} !important`,\n },\n '&.baseIncorrect': {\n border: `2px solid ${color.incorrect()} !important`,\n },\n '&.selected': {\n opacity: 0.7,\n },\n}));\n\nconst StyledSpan = styled(StaticHTMLSpan)(() => ({\n cursor: 'grab',\n backgroundColor: color.background(),\n '&.hiddenSpan': {\n visibility: 'hidden',\n },\n}));\n\nconst PossibleResponse = ({\n canDrag,\n containerStyle,\n data,\n onDragBegin,\n answerChoiceTransparency,\n isOverlay,\n selectedResponse,\n onSelectClick,\n onPlacementClick,\n}) => {\n const rootRef = useRef(null);\n const longPressTimer = useRef(null);\n\n const { setNodeRef, attributes, listeners, isDragging } = useDraggable({\n id: `possible-response-${data.id}`,\n data: {\n id: data.id,\n value: data.value,\n containerIndex: data.containerIndex,\n },\n disabled: !canDrag,\n });\n\n const isSelected =\n !!selectedResponse && selectedResponse.id === data.id && selectedResponse.containerIndex === data.containerIndex;\n\n const handleClick = (e) => {\n if (!canDrag) return;\n\n e.stopPropagation();\n\n const isPlaced = data.containerIndex !== undefined;\n\n if (isSelected) {\n // Clicking the already-selected tile again deselects it.\n onSelectClick?.(data);\n } else if (selectedResponse && isPlaced) {\n // Something else is selected, and this tile is already inside a container:\n // place the selection into that same container (a swap/insert, handled by the\n // existing handleOnAnswerSelect logic).\n onPlacementClick?.(data.containerIndex);\n } else {\n // Nothing selected yet, or this is a pool item (pool items are never placement\n // targets — the pool itself, in possible-responses.jsx, is): select this tile.\n onSelectClick?.(data);\n }\n };\n\n const handleTouchEnd = () => {\n clearTimeout(longPressTimer.current);\n };\n\n const handleTouchMove = () => {\n clearTimeout(longPressTimer.current);\n };\n\n const handleTouchStart = (e) => {\n e.preventDefault();\n longPressTimer.current = setTimeout(() => {\n if (canDrag && rootRef.current) {\n onDragBegin(data);\n }\n }, 500); // start drag after 500ms (touch and hold duration) for chromebooks and other touch devices\n };\n\n useEffect(() => {\n const node = rootRef.current;\n\n if (!node) return;\n\n node.addEventListener('touchstart', handleTouchStart, { passive: false });\n node.addEventListener('touchend', handleTouchEnd);\n node.addEventListener('touchmove', handleTouchMove, { passive: false });\n\n return () => {\n node.removeEventListener('touchstart', handleTouchStart);\n node.removeEventListener('touchend', handleTouchEnd);\n node.removeEventListener('touchmove', handleTouchMove);\n };\n }, [canDrag, data]);\n\n const { isCorrect } = data || {};\n const evaluationStyle = {\n fontSize: 14,\n position: 'absolute',\n bottom: '3px',\n right: '3px',\n };\n const correctnessClass = isCorrect === true ? 'baseCorrect' : isCorrect === false ? 'baseIncorrect' : undefined;\n\n const imgRegex = /<img[^>]+src=\"([^\">]+)\"/;\n const containsImage = imgRegex.test(data.value);\n\n const containerClassNames = classNames({\n answerChoiceTransparency: answerChoiceTransparency && !isDragging,\n [correctnessClass]: !!correctnessClass,\n textAnswerChoiceStyle: !containsImage && !isOverlay,\n selected: isSelected && !isDragging,\n });\n\n const promptClassNames = classNames({ hiddenSpan: data.hidden });\n\n return (\n <BaseContainer\n className={containerClassNames}\n style={containerStyle}\n ref={(ref) => {\n rootRef.current = ref;\n setNodeRef(ref);\n }}\n onClick={handleClick}\n {...listeners}\n {...attributes}\n >\n <StyledSpan html={data.value} className={promptClassNames} />\n <EvaluationIcon isCorrect={data.isCorrect} containerStyle={evaluationStyle} />\n </BaseContainer>\n );\n};\n\nPossibleResponse.propTypes = {\n canDrag: PropTypes.bool.isRequired,\n containerStyle: PropTypes.object,\n data: PropTypes.object.isRequired,\n onDragBegin: PropTypes.func.isRequired,\n answerChoiceTransparency: PropTypes.bool,\n isOverlay: PropTypes.bool,\n selectedResponse: PropTypes.object,\n onSelectClick: PropTypes.func,\n onPlacementClick: PropTypes.func,\n};\n\nPossibleResponse.defaultProps = {\n containerStyle: {},\n answerChoiceTransparency: false,\n isOverlay: false,\n selectedResponse: null,\n};\n\nexport default PossibleResponse;\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"possible-response.js","names":["_react","_interopRequireWildcard","require","_propTypes","_interopRequireDefault","_classnames","_styles","_core","_renderUi","_evaluationIcon","_staticHtmlSpan","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","BaseContainer","styled","position","backgroundColor","color","white","border","borderDark","display","alignItems","justifyContent","minHeight","width","pointerEvents","padding","margin","transparent","correct","incorrect","StyledSpan","StaticHTMLSpan","cursor","background","visibility","PossibleResponse","canDrag","containerStyle","data","onDragBegin","answerChoiceTransparency","isOverlay","rootRef","useRef","longPressTimer","setNodeRef","attributes","listeners","isDragging","useDraggable","id","value","containerIndex","disabled","handleTouchEnd","clearTimeout","current","handleTouchMove","handleTouchStart","preventDefault","setTimeout","useEffect","node","addEventListener","passive","removeEventListener","isCorrect","evaluationStyle","fontSize","bottom","right","correctnessClass","undefined","imgRegex","containsImage","test","containerClassNames","classNames","textAnswerChoiceStyle","promptClassNames","hiddenSpan","hidden","createElement","_extends2","className","style","ref","html","propTypes","PropTypes","bool","isRequired","object","func","defaultProps","_default","exports"],"sources":["../src/possible-response.jsx"],"sourcesContent":["import React, { useEffect, useRef } from 'react';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\nimport { styled } from '@mui/material/styles';\nimport { useDraggable } from '@dnd-kit/core';\nimport { color } from '@pie-lib/render-ui';\n\nimport EvaluationIcon from './evaluation-icon';\nimport StaticHTMLSpan from './static-html-span';\n\nconst BaseContainer = styled('div')(() => ({\n position: 'relative',\n backgroundColor: color.white(),\n border: `1px solid ${color.borderDark()}`,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n minHeight: '28px',\n width: 'fit-content',\n '& span img': {\n // Added for touch devices, for image content.\n // This will prevent the context menu from appearing and not allowing other interactions with the image.\n // If interactions with the image in the token will be requested we should handle only the context Menu.\n pointerEvents: 'none',\n },\n '&.textAnswerChoiceStyle': {\n padding: '0 10px',\n margin: '4px 6px !important',\n },\n '&.answerChoiceTransparency': {\n border: 'none',\n backgroundColor: `${color.transparent()}`,\n '&:hover': {\n border: `1px solid ${color.borderDark()}`,\n },\n },\n '&.baseCorrect': {\n border: `2px solid ${color.correct()} !important`,\n },\n '&.baseIncorrect': {\n border: `2px solid ${color.incorrect()} !important`,\n },\n}));\n\nconst StyledSpan = styled(StaticHTMLSpan)(() => ({\n cursor: 'grab',\n backgroundColor: color.background(),\n '&.hiddenSpan': {\n visibility: 'hidden',\n },\n}));\n\nconst PossibleResponse = ({ canDrag, containerStyle, data, onDragBegin, answerChoiceTransparency, isOverlay }) => {\n const rootRef = useRef(null);\n const longPressTimer = useRef(null);\n\n const { setNodeRef, attributes, listeners, isDragging } = useDraggable({\n id: `possible-response-${data.id}`,\n data: {\n id: data.id,\n value: data.value,\n containerIndex: data.containerIndex,\n },\n disabled: !canDrag,\n });\n\n const handleTouchEnd = () => {\n clearTimeout(longPressTimer.current);\n };\n\n const handleTouchMove = () => {\n clearTimeout(longPressTimer.current);\n };\n\n const handleTouchStart = (e) => {\n e.preventDefault();\n longPressTimer.current = setTimeout(() => {\n if (canDrag && rootRef.current) {\n onDragBegin(data);\n }\n }, 500); // start drag after 500ms (touch and hold duration) for chromebooks and other touch devices\n };\n\n useEffect(() => {\n const node = rootRef.current;\n\n if (!node) return;\n\n node.addEventListener('touchstart', handleTouchStart, { passive: false });\n node.addEventListener('touchend', handleTouchEnd);\n node.addEventListener('touchmove', handleTouchMove, { passive: false });\n\n return () => {\n node.removeEventListener('touchstart', handleTouchStart);\n node.removeEventListener('touchend', handleTouchEnd);\n node.removeEventListener('touchmove', handleTouchMove);\n };\n }, [canDrag, data]);\n\n const { isCorrect } = data || {};\n const evaluationStyle = {\n fontSize: 14,\n position: 'absolute',\n bottom: '3px',\n right: '3px',\n };\n const correctnessClass = isCorrect === true ? 'baseCorrect' : isCorrect === false ? 'baseIncorrect' : undefined;\n\n const imgRegex = /<img[^>]+src=\"([^\">]+)\"/;\n const containsImage = imgRegex.test(data.value);\n\n const containerClassNames = classNames({\n answerChoiceTransparency: answerChoiceTransparency && !isDragging,\n [correctnessClass]: !!correctnessClass,\n textAnswerChoiceStyle: !containsImage && !isOverlay,\n });\n\n const promptClassNames = classNames({ hiddenSpan: data.hidden });\n\n return (\n <BaseContainer\n className={containerClassNames}\n style={containerStyle}\n ref={(ref) => {\n rootRef.current = ref;\n setNodeRef(ref);\n }}\n {...listeners}\n {...attributes}\n >\n <StyledSpan html={data.value} className={promptClassNames} />\n <EvaluationIcon isCorrect={data.isCorrect} containerStyle={evaluationStyle} />\n </BaseContainer>\n );\n};\n\nPossibleResponse.propTypes = {\n canDrag: PropTypes.bool.isRequired,\n containerStyle: PropTypes.object,\n data: PropTypes.object.isRequired,\n onDragBegin: PropTypes.func.isRequired,\n answerChoiceTransparency: PropTypes.bool,\n isOverlay: PropTypes.bool,\n};\n\nPossibleResponse.defaultProps = {\n containerStyle: {},\n answerChoiceTransparency: false,\n isOverlay: false,\n};\n\nexport default PossibleResponse;\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -27,41 +27,24 @@ const PossibleResponses = ({
|
|
|
27
27
|
answerChoiceTransparency,
|
|
28
28
|
customStyle,
|
|
29
29
|
isVertical,
|
|
30
|
-
minHeight
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
disabled: !canDrag,
|
|
49
|
-
isVerticalPool: isVertical,
|
|
50
|
-
minHeight: minHeight
|
|
51
|
-
}, (data || []).map(item => /*#__PURE__*/_react.default.createElement(_possibleResponse.default, {
|
|
52
|
-
canDrag: canDrag,
|
|
53
|
-
key: item.id,
|
|
54
|
-
data: item,
|
|
55
|
-
onDragBegin: onDragBegin,
|
|
56
|
-
answerChoiceTransparency: answerChoiceTransparency,
|
|
57
|
-
containerStyle: {
|
|
58
|
-
margin: '4px'
|
|
59
|
-
},
|
|
60
|
-
selectedResponse: selectedResponse,
|
|
61
|
-
onSelectClick: onSelectClick,
|
|
62
|
-
onPlacementClick: onPlacementClick
|
|
63
|
-
}))));
|
|
64
|
-
};
|
|
30
|
+
minHeight
|
|
31
|
+
}) => /*#__PURE__*/_react.default.createElement(BaseContainer, {
|
|
32
|
+
style: customStyle
|
|
33
|
+
}, /*#__PURE__*/_react.default.createElement(_drag.ICADroppablePlaceholder, {
|
|
34
|
+
id: "ica-board",
|
|
35
|
+
disabled: !canDrag,
|
|
36
|
+
isVerticalPool: isVertical,
|
|
37
|
+
minHeight: minHeight
|
|
38
|
+
}, (data || []).map(item => /*#__PURE__*/_react.default.createElement(_possibleResponse.default, {
|
|
39
|
+
canDrag: canDrag,
|
|
40
|
+
key: item.id,
|
|
41
|
+
data: item,
|
|
42
|
+
onDragBegin: onDragBegin,
|
|
43
|
+
answerChoiceTransparency: answerChoiceTransparency,
|
|
44
|
+
containerStyle: {
|
|
45
|
+
margin: '4px'
|
|
46
|
+
}
|
|
47
|
+
}))));
|
|
65
48
|
PossibleResponses.propTypes = {
|
|
66
49
|
canDrag: _propTypes.default.bool.isRequired,
|
|
67
50
|
data: _propTypes.default.array.isRequired,
|
|
@@ -69,10 +52,7 @@ PossibleResponses.propTypes = {
|
|
|
69
52
|
answerChoiceTransparency: _propTypes.default.bool,
|
|
70
53
|
customStyle: _propTypes.default.object,
|
|
71
54
|
isVertical: _propTypes.default.bool,
|
|
72
|
-
minHeight: _propTypes.default.number
|
|
73
|
-
selectedResponse: _propTypes.default.object,
|
|
74
|
-
onSelectClick: _propTypes.default.func,
|
|
75
|
-
onPlacementClick: _propTypes.default.func
|
|
55
|
+
minHeight: _propTypes.default.number
|
|
76
56
|
};
|
|
77
57
|
var _default = exports.default = PossibleResponses;
|
|
78
58
|
//# sourceMappingURL=possible-responses.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"possible-responses.js","names":["_react","_interopRequireDefault","require","_propTypes","_styles","_renderUi","_drag","_possibleResponse","BaseContainer","styled","theme","backgroundColor","color","background","margin","spacing","display","alignItems","width","PossibleResponses","canDrag","data","onDragBegin","answerChoiceTransparency","customStyle","isVertical","minHeight","
|
|
1
|
+
{"version":3,"file":"possible-responses.js","names":["_react","_interopRequireDefault","require","_propTypes","_styles","_renderUi","_drag","_possibleResponse","BaseContainer","styled","theme","backgroundColor","color","background","margin","spacing","display","alignItems","width","PossibleResponses","canDrag","data","onDragBegin","answerChoiceTransparency","customStyle","isVertical","minHeight","default","createElement","style","ICADroppablePlaceholder","id","disabled","isVerticalPool","map","item","key","containerStyle","propTypes","PropTypes","bool","isRequired","array","func","object","number","_default","exports"],"sources":["../src/possible-responses.jsx"],"sourcesContent":["import React from 'react';\nimport PropTypes from 'prop-types';\nimport { styled } from '@mui/material/styles';\nimport { color } from '@pie-lib/render-ui';\nimport { ICADroppablePlaceholder } from '@pie-lib/drag';\n\nimport PossibleResponse from './possible-response';\n\nconst BaseContainer = styled('div')(({ theme }) => ({\n backgroundColor: color.background(),\n margin: theme.spacing(2),\n display: 'flex',\n alignItems: 'center',\n width: 'fit-content',\n}));\n\nconst PossibleResponses = ({\n canDrag,\n data,\n onDragBegin,\n answerChoiceTransparency,\n customStyle,\n isVertical,\n minHeight,\n}) => (\n <BaseContainer style={customStyle}>\n <ICADroppablePlaceholder id=\"ica-board\" disabled={!canDrag} isVerticalPool={isVertical} minHeight={minHeight}>\n {(data || []).map((item) => (\n <PossibleResponse\n canDrag={canDrag}\n key={item.id}\n data={item}\n onDragBegin={onDragBegin}\n answerChoiceTransparency={answerChoiceTransparency}\n containerStyle={{ margin: '4px' }}\n />\n ))}\n </ICADroppablePlaceholder>\n </BaseContainer>\n);\n\nPossibleResponses.propTypes = {\n canDrag: PropTypes.bool.isRequired,\n data: PropTypes.array.isRequired,\n onDragBegin: PropTypes.func.isRequired,\n answerChoiceTransparency: PropTypes.bool,\n customStyle: PropTypes.object,\n isVertical: PropTypes.bool,\n minHeight: PropTypes.number,\n};\n\nexport default PossibleResponses;\n"],"mappings":";;;;;;;AAAA,IAAAA,MAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,UAAA,GAAAF,sBAAA,CAAAC,OAAA;AACA,IAAAE,OAAA,GAAAF,OAAA;AACA,IAAAG,SAAA,GAAAH,OAAA;AACA,IAAAI,KAAA,GAAAJ,OAAA;AAEA,IAAAK,iBAAA,GAAAN,sBAAA,CAAAC,OAAA;AAEA,MAAMM,aAAa,GAAG,IAAAC,cAAM,EAAC,KAAK,CAAC,CAAC,CAAC;EAAEC;AAAM,CAAC,MAAM;EAClDC,eAAe,EAAEC,eAAK,CAACC,UAAU,CAAC,CAAC;EACnCC,MAAM,EAAEJ,KAAK,CAACK,OAAO,CAAC,CAAC,CAAC;EACxBC,OAAO,EAAE,MAAM;EACfC,UAAU,EAAE,QAAQ;EACpBC,KAAK,EAAE;AACT,CAAC,CAAC,CAAC;AAEH,MAAMC,iBAAiB,GAAGA,CAAC;EACzBC,OAAO;EACPC,IAAI;EACJC,WAAW;EACXC,wBAAwB;EACxBC,WAAW;EACXC,UAAU;EACVC;AACF,CAAC,kBACC1B,MAAA,CAAA2B,OAAA,CAAAC,aAAA,CAACpB,aAAa;EAACqB,KAAK,EAAEL;AAAY,gBAChCxB,MAAA,CAAA2B,OAAA,CAAAC,aAAA,CAACtB,KAAA,CAAAwB,uBAAuB;EAACC,EAAE,EAAC,WAAW;EAACC,QAAQ,EAAE,CAACZ,OAAQ;EAACa,cAAc,EAAER,UAAW;EAACC,SAAS,EAAEA;AAAU,GAC1G,CAACL,IAAI,IAAI,EAAE,EAAEa,GAAG,CAAEC,IAAI,iBACrBnC,MAAA,CAAA2B,OAAA,CAAAC,aAAA,CAACrB,iBAAA,CAAAoB,OAAgB;EACfP,OAAO,EAAEA,OAAQ;EACjBgB,GAAG,EAAED,IAAI,CAACJ,EAAG;EACbV,IAAI,EAAEc,IAAK;EACXb,WAAW,EAAEA,WAAY;EACzBC,wBAAwB,EAAEA,wBAAyB;EACnDc,cAAc,EAAE;IAAEvB,MAAM,EAAE;EAAM;AAAE,CACnC,CACF,CACsB,CACZ,CAChB;AAEDK,iBAAiB,CAACmB,SAAS,GAAG;EAC5BlB,OAAO,EAAEmB,kBAAS,CAACC,IAAI,CAACC,UAAU;EAClCpB,IAAI,EAAEkB,kBAAS,CAACG,KAAK,CAACD,UAAU;EAChCnB,WAAW,EAAEiB,kBAAS,CAACI,IAAI,CAACF,UAAU;EACtClB,wBAAwB,EAAEgB,kBAAS,CAACC,IAAI;EACxChB,WAAW,EAAEe,kBAAS,CAACK,MAAM;EAC7BnB,UAAU,EAAEc,kBAAS,CAACC,IAAI;EAC1Bd,SAAS,EAAEa,kBAAS,CAACM;AACvB,CAAC;AAAC,IAAAC,QAAA,GAAAC,OAAA,CAAApB,OAAA,GAEaR,iBAAiB","ignoreList":[]}
|
package/lib/root.js
CHANGED
|
@@ -23,17 +23,10 @@ var _interactiveSection = _interopRequireDefault(require("./interactive-section"
|
|
|
23
23
|
var _possibleResponses2 = _interopRequireDefault(require("./possible-responses"));
|
|
24
24
|
var _utilsCorrectness = require("./utils-correctness");
|
|
25
25
|
var _possibleResponse = _interopRequireDefault(require("./possible-response"));
|
|
26
|
-
var _keyboardCoordinates = require("./keyboard-coordinates");
|
|
27
26
|
const {
|
|
28
27
|
translator
|
|
29
28
|
} = _translator.default;
|
|
30
29
|
const generateId = () => Math.random().toString(36).substring(2) + new Date().getTime().toString(36);
|
|
31
|
-
|
|
32
|
-
// A click that lands right after a real drag gesture ends (pointer drag-and-drop, or
|
|
33
|
-
// the browser's own synthetic click for a keyboard Space/Enter) must be ignored by the
|
|
34
|
-
// click-to-select/click-to-place handlers below, or it would immediately reopen or
|
|
35
|
-
// re-trigger a selection for a drag that just completed.
|
|
36
|
-
const CLICK_AFTER_DRAG_GUARD_MS = 250;
|
|
37
30
|
const StyledUiLayout = (0, _styles.styled)(_renderUi.UiLayout)({
|
|
38
31
|
color: _renderUi.color.text(),
|
|
39
32
|
backgroundColor: _renderUi.color.background(),
|
|
@@ -63,8 +56,7 @@ class ImageClozeAssociationComponent extends _react.default.Component {
|
|
|
63
56
|
if (active?.data?.current) {
|
|
64
57
|
this.setState({
|
|
65
58
|
draggingElement: active.data.current,
|
|
66
|
-
isValidDrop: false
|
|
67
|
-
selectedResponse: active.data.current
|
|
59
|
+
isValidDrop: false
|
|
68
60
|
});
|
|
69
61
|
}
|
|
70
62
|
});
|
|
@@ -92,8 +84,6 @@ class ImageClozeAssociationComponent extends _react.default.Component {
|
|
|
92
84
|
},
|
|
93
85
|
isValidDrop: shouldDisableAnimation
|
|
94
86
|
});
|
|
95
|
-
this.cancelSelection();
|
|
96
|
-
this.lastDragEndAt = Date.now();
|
|
97
87
|
if (!over || !active) {
|
|
98
88
|
return;
|
|
99
89
|
}
|
|
@@ -101,102 +91,13 @@ class ImageClozeAssociationComponent extends _react.default.Component {
|
|
|
101
91
|
return;
|
|
102
92
|
}
|
|
103
93
|
if (over.id === 'ica-board') {
|
|
104
|
-
|
|
105
|
-
this.handleOnAnswerRemove(draggedItem);
|
|
106
|
-
}
|
|
94
|
+
this.handleOnAnswerRemove(draggedItem);
|
|
107
95
|
return;
|
|
108
96
|
}
|
|
109
97
|
if (responseArea) {
|
|
110
98
|
this.handleOnAnswerSelect(draggedItem, responseArea.containerIndex);
|
|
111
99
|
}
|
|
112
100
|
});
|
|
113
|
-
(0, _defineProperty2.default)(this, "onDragCancel", () => {
|
|
114
|
-
this.setState({
|
|
115
|
-
draggingElement: {
|
|
116
|
-
id: '',
|
|
117
|
-
value: ''
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
this.cancelSelection();
|
|
121
|
-
this.lastDragEndAt = Date.now();
|
|
122
|
-
});
|
|
123
|
-
(0, _defineProperty2.default)(this, "isSameResponse", (a, b) => !!a && !!b && a.id === b.id && a.containerIndex === b.containerIndex);
|
|
124
|
-
// Click-to-select semantics: selecting the currently-selected response again clears
|
|
125
|
-
// the selection instead of re-selecting it.
|
|
126
|
-
(0, _defineProperty2.default)(this, "toggleResponseSelection", data => {
|
|
127
|
-
this.setState(state => ({
|
|
128
|
-
selectedResponse: this.isSameResponse(state.selectedResponse, data) ? null : data
|
|
129
|
-
}));
|
|
130
|
-
});
|
|
131
|
-
(0, _defineProperty2.default)(this, "cancelSelection", () => {
|
|
132
|
-
this.setState({
|
|
133
|
-
selectedResponse: null
|
|
134
|
-
});
|
|
135
|
-
});
|
|
136
|
-
// If a real dnd-kit drag (started via keyboard Space/Enter) is still live when a
|
|
137
|
-
// click completes the placement below, it needs to be cleanly ended — otherwise
|
|
138
|
-
// dnd-kit would still think a drag is in progress. Escape is already configured as
|
|
139
|
-
// this sensor's cancel key (see the keyboardCodes passed to DragProvider below), and
|
|
140
|
-
// dispatching it as a real DOM KeyboardEvent is how dnd-kit's own document-level
|
|
141
|
-
// listener is reached from outside its sensor.
|
|
142
|
-
//
|
|
143
|
-
// Only dispatch when a drag is actually live (draggingElement.id is truthy) — this is
|
|
144
|
-
// a synthetic Escape keydown on `document`, so an unconditional dispatch would also be
|
|
145
|
-
// observed by any other document-level Escape listener (host player modals/dialogs,
|
|
146
|
-
// or another mounted instance of this same component) even when nothing here actually
|
|
147
|
-
// needed cancelling.
|
|
148
|
-
(0, _defineProperty2.default)(this, "endAnyLiveKeyboardDrag", () => {
|
|
149
|
-
if (!this.state.draggingElement.id) {
|
|
150
|
-
return;
|
|
151
|
-
}
|
|
152
|
-
document.dispatchEvent(new KeyboardEvent('keydown', {
|
|
153
|
-
code: 'Escape',
|
|
154
|
-
bubbles: true,
|
|
155
|
-
cancelable: true
|
|
156
|
-
}));
|
|
157
|
-
});
|
|
158
|
-
(0, _defineProperty2.default)(this, "placeSelectedResponse", containerIndex => {
|
|
159
|
-
const {
|
|
160
|
-
selectedResponse
|
|
161
|
-
} = this.state;
|
|
162
|
-
if (!selectedResponse) {
|
|
163
|
-
return;
|
|
164
|
-
}
|
|
165
|
-
if (containerIndex === undefined) {
|
|
166
|
-
// Placing into the pool = removing it from wherever it currently is
|
|
167
|
-
if (selectedResponse.containerIndex !== undefined) {
|
|
168
|
-
this.handleOnAnswerRemove(selectedResponse);
|
|
169
|
-
}
|
|
170
|
-
} else {
|
|
171
|
-
this.handleOnAnswerSelect(selectedResponse, containerIndex);
|
|
172
|
-
}
|
|
173
|
-
this.cancelSelection();
|
|
174
|
-
this.endAnyLiveKeyboardDrag();
|
|
175
|
-
this.lastDragEndAt = Date.now();
|
|
176
|
-
});
|
|
177
|
-
(0, _defineProperty2.default)(this, "isClickSoonAfterDragEnd", () => Date.now() - this.lastDragEndAt < CLICK_AFTER_DRAG_GUARD_MS);
|
|
178
|
-
(0, _defineProperty2.default)(this, "onResponseClick", data => {
|
|
179
|
-
if (this.isClickSoonAfterDragEnd()) {
|
|
180
|
-
return;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
// A click that selects/deselects/switches a tile must end any dnd-kit drag that's
|
|
184
|
-
// still live from an earlier keyboard Space/Enter pick-up first — otherwise dnd-kit
|
|
185
|
-
// keeps thinking that earlier item is being dragged (it ignores new sensor
|
|
186
|
-
// activation while a drag is active) while selectedResponse visually points at
|
|
187
|
-
// whatever this click just selected. Ending the stale drag first (rather than
|
|
188
|
-
// after) matters: ending it also cancels the current selection as a side effect
|
|
189
|
-
// (see onDragCancel above), so doing it before
|
|
190
|
-
// toggleResponseSelection lets this click's own selection be the one that sticks.
|
|
191
|
-
this.endAnyLiveKeyboardDrag();
|
|
192
|
-
this.toggleResponseSelection(data);
|
|
193
|
-
});
|
|
194
|
-
(0, _defineProperty2.default)(this, "onPlacementClick", containerIndex => {
|
|
195
|
-
if (this.isClickSoonAfterDragEnd()) {
|
|
196
|
-
return;
|
|
197
|
-
}
|
|
198
|
-
this.placeSelectedResponse(containerIndex);
|
|
199
|
-
});
|
|
200
101
|
(0, _defineProperty2.default)(this, "renderDragOverlay", () => {
|
|
201
102
|
const {
|
|
202
103
|
draggingElement
|
|
@@ -387,10 +288,8 @@ class ImageClozeAssociationComponent extends _react.default.Component {
|
|
|
387
288
|
})),
|
|
388
289
|
maxResponsePerZone: _maxResponsePerZone || 1,
|
|
389
290
|
showCorrect: false,
|
|
390
|
-
isValidDrop: false
|
|
391
|
-
selectedResponse: null
|
|
291
|
+
isValidDrop: false
|
|
392
292
|
};
|
|
393
|
-
this.lastDragEndAt = 0;
|
|
394
293
|
}
|
|
395
294
|
render() {
|
|
396
295
|
const {
|
|
@@ -471,10 +370,7 @@ class ImageClozeAssociationComponent extends _react.default.Component {
|
|
|
471
370
|
responseAreaFill,
|
|
472
371
|
responseContainerPadding,
|
|
473
372
|
imageDropTargetPadding,
|
|
474
|
-
maxResponsePerZone
|
|
475
|
-
selectedResponse: this.state.selectedResponse,
|
|
476
|
-
onSelectClick: this.onResponseClick,
|
|
477
|
-
onPlacementClick: this.onPlacementClick
|
|
373
|
+
maxResponsePerZone
|
|
478
374
|
};
|
|
479
375
|
const renderImage = () => /*#__PURE__*/_react.default.createElement(_imageContainer.default, (0, _extends2.default)({}, sharedImageProps, {
|
|
480
376
|
canDrag: showCorrect && showToggle ? false : !disabled,
|
|
@@ -495,22 +391,12 @@ class ImageClozeAssociationComponent extends _react.default.Component {
|
|
|
495
391
|
minWidth: isVertical ? '130px' : image?.width || 'fit-content'
|
|
496
392
|
},
|
|
497
393
|
isVertical: isVertical,
|
|
498
|
-
minHeight: isVertical ? image?.height : undefined
|
|
499
|
-
selectedResponse: this.state.selectedResponse,
|
|
500
|
-
onSelectClick: this.onResponseClick,
|
|
501
|
-
onPlacementClick: this.onPlacementClick
|
|
394
|
+
minHeight: isVertical ? image?.height : undefined
|
|
502
395
|
}));
|
|
503
396
|
};
|
|
504
397
|
return /*#__PURE__*/_react.default.createElement(_drag.DragProvider, {
|
|
505
398
|
onDragStart: this.onDragStart,
|
|
506
|
-
onDragEnd: this.onDragEnd
|
|
507
|
-
onDragCancel: this.onDragCancel,
|
|
508
|
-
keyboardCoordinateGetter: _keyboardCoordinates.closestDroppableKeyboardCoordinates,
|
|
509
|
-
keyboardCodes: {
|
|
510
|
-
start: ['Space', 'Enter'],
|
|
511
|
-
cancel: ['Escape'],
|
|
512
|
-
end: ['Space', 'Enter']
|
|
513
|
-
}
|
|
399
|
+
onDragEnd: this.onDragEnd
|
|
514
400
|
}, /*#__PURE__*/_react.default.createElement(StyledUiLayout, {
|
|
515
401
|
extraCSSRules: extraCSSRules,
|
|
516
402
|
id: 'main-container',
|