@citolab/qti-components 7.8.1 → 7.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,4 +5,4 @@ var configContext = createContext(Symbol("configContext"));
5
5
  export {
6
6
  configContext
7
7
  };
8
- //# sourceMappingURL=chunk-ERYHQVOT.js.map
8
+ //# sourceMappingURL=chunk-BHJSX3Q6.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/lib/exports/config.context.ts"],"sourcesContent":["import { createContext } from '@lit/context';\n\nexport type CorrectResponseMode = 'internal' | 'full';\n\nexport interface ConfigContext {\n infoItemCategory?: string;\n reportValidityAfterScoring?: boolean;\n disableAfterIfMaxChoicesReached?: boolean;\n correctResponseMode?: CorrectResponseMode;\n inlineChoicePrompt?: string;\n}\n\nexport const configContext = createContext<Readonly<ConfigContext>>(Symbol('configContext'));\n"],"mappings":";AAAA,SAAS,qBAAqB;AAYvB,IAAM,gBAAgB,cAAuC,OAAO,eAAe,CAAC;","names":[]}
1
+ {"version":3,"sources":["../../src/lib/exports/config.context.ts"],"sourcesContent":["import { createContext } from '@lit/context';\n\nexport type CorrectResponseMode = 'internal' | 'full';\n\nexport interface ConfigContext {\n infoItemCategory?: string;\n reportValidityAfterScoring?: boolean;\n disableAfterIfMaxChoicesReached?: boolean;\n correctResponseMode?: CorrectResponseMode;\n inlineChoicePrompt?: string;\n fullCorrectResponseOnlyWhenIncorrect?: boolean;\n}\n\nexport const configContext = createContext<Readonly<ConfigContext>>(Symbol('configContext'));\n"],"mappings":";AAAA,SAAS,qBAAqB;AAavB,IAAM,gBAAgB,cAAuC,OAAO,eAAe,CAAC;","names":[]}
@@ -12,7 +12,7 @@ import {
12
12
  } from "./chunk-4OGJBG35.js";
13
13
  import {
14
14
  configContext
15
- } from "./chunk-ERYHQVOT.js";
15
+ } from "./chunk-BHJSX3Q6.js";
16
16
  import {
17
17
  __decorateClass
18
18
  } from "./chunk-H2JE6IVU.js";
@@ -362,4 +362,4 @@ export {
362
362
  ItemShowCorrectResponse,
363
363
  QtiItem
364
364
  };
365
- //# sourceMappingURL=chunk-4QSZJYSB.js.map
365
+ //# sourceMappingURL=chunk-IHE5M7QU.js.map
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-NJNQOQUU.js";
4
4
  import {
5
5
  configContext
6
- } from "./chunk-ERYHQVOT.js";
6
+ } from "./chunk-BHJSX3Q6.js";
7
7
  import {
8
8
  __decorateClass
9
9
  } from "./chunk-H2JE6IVU.js";
@@ -75,7 +75,8 @@ var Interaction = class extends LitElement {
75
75
  if (!responseVariable) {
76
76
  return;
77
77
  }
78
- if (!show || this.correctness === "correct" /* Correct */) {
78
+ const showFullCorrectResponse = show && (this?.configContext?.fullCorrectResponseOnlyWhenIncorrect === false || this.correctness !== "correct" /* Correct */);
79
+ if (!showFullCorrectResponse) {
79
80
  if (!nextSiblingIsFullCorrectResponse) {
80
81
  return;
81
82
  }
@@ -84,9 +85,6 @@ var Interaction = class extends LitElement {
84
85
  if (nextSiblingIsFullCorrectResponse) {
85
86
  return;
86
87
  }
87
- if (this.correctness === "correct" /* Correct */) {
88
- return;
89
- }
90
88
  const clone = this.cloneNode(true);
91
89
  const containerDiv = document.createElement("div");
92
90
  containerDiv.classList.add("full-correct-response");
@@ -205,4 +203,4 @@ export {
205
203
  Correctness,
206
204
  Interaction
207
205
  };
208
- //# sourceMappingURL=chunk-HFAUM56X.js.map
206
+ //# sourceMappingURL=chunk-P4QBOVQ2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/lib/exports/interaction.ts"],"sourcesContent":["import { property, state } from 'lit/decorators.js';\nimport { LitElement } from 'lit';\nimport { consume } from '@lit/context';\n\nimport { configContext } from './config.context.ts';\nimport { itemContext } from './qti-assessment-item.context.ts';\n\nimport type { ConfigContext } from './config.context.ts';\nimport type { ResponseVariable } from './variables';\nimport type { IInteraction } from './interaction.interface';\nimport type { ItemContext } from './item.context.ts';\n\nexport enum Correctness {\n Correct = 'correct',\n PartiallyCorrect = 'partially-correct',\n Incorrect = 'incorrect'\n}\n\nexport abstract class Interaction extends LitElement implements IInteraction {\n @consume({ context: itemContext, subscribe: true })\n private _context: ItemContext;\n\n @consume({ context: configContext, subscribe: true })\n protected configContext: ConfigContext;\n\n static formAssociated = true;\n protected _internals: ElementInternals;\n\n get internals(): ElementInternals {\n return this._internals;\n }\n\n @property({ type: String, attribute: 'response-identifier' }) responseIdentifier;\n\n @property({ reflect: true, type: Boolean }) disabled = false;\n\n @property({ reflect: true, type: Boolean }) readonly = false;\n\n @state()\n protected _isFullCorrectResponse: boolean;\n\n get isFullCorrectResponse(): Readonly<boolean> {\n return this._isFullCorrectResponse;\n }\n\n set isFullCorrectResponse(val: Readonly<boolean>) {\n this._isFullCorrectResponse = val as boolean;\n if (val) {\n this.disabled = true;\n this.setAttribute('response-identifier', this.responseIdentifier + '_cr');\n }\n }\n\n /* PK: Correct response */\n @state()\n protected _correctResponse: string | string[];\n\n get correctResponse(): Readonly<string | string[]> {\n return this._correctResponse;\n }\n\n set correctResponse(val: Readonly<string | string[]>) {\n this._correctResponse = val as string | string[];\n }\n\n get correctness(): Readonly<Correctness | null> {\n const responseVariable = this.responseVariable;\n if (!responseVariable || responseVariable.correctResponse === null) return null;\n\n return responseVariable.correctResponse === responseVariable.value ? Correctness.Correct : Correctness.Incorrect;\n }\n\n get isInline(): boolean {\n return false;\n }\n\n get responseVariable(): ResponseVariable | undefined {\n // Get all response variables\n const responseVariables = this._context.variables.filter(v => v.type === 'response') as ResponseVariable[];\n\n // Get the response identifier for this interaction\n const responseIdentifier = this.getAttribute('response-identifier');\n\n // Return the matching response variable for this interaction\n return responseVariables.find(v => v.identifier === responseIdentifier);\n }\n\n public toggleCorrectResponse(show: boolean): void {\n const correctResponseMode = this?.configContext?.correctResponseMode || 'internal';\n\n if (correctResponseMode === 'full') {\n this.toggleFullCorrectResponse(show);\n } else {\n this.toggleInternalCorrectResponse(show);\n }\n }\n\n protected async toggleFullCorrectResponse(show: boolean): Promise<void> {\n const nextSibling = this.nextSibling;\n const nextSiblingIsFullCorrectResponse =\n nextSibling instanceof HTMLDivElement && nextSibling?.classList.contains('full-correct-response');\n const responseVariable = this.responseVariable;\n\n if (!responseVariable) {\n return;\n }\n\n const showFullCorrectResponse = show && (this?.configContext?.fullCorrectResponseOnlyWhenIncorrect === false || this.correctness !== Correctness.Correct)\n\n if (!showFullCorrectResponse) {\n if (!nextSiblingIsFullCorrectResponse) {\n return;\n }\n // Remove cloned interaction\n this.parentElement?.removeChild(nextSibling);\n }\n\n if (nextSiblingIsFullCorrectResponse) {\n return; // Already exists\n }\n\n\n // Add a clone of interaction with the correct response\n const clone = this.cloneNode(true) as Interaction;\n\n const containerDiv = document.createElement('div');\n containerDiv.classList.add('full-correct-response');\n if (this.isInline) {\n containerDiv.classList.add('full-correct-response-inline');\n } else {\n containerDiv.classList.add('full-correct-response-block');\n }\n containerDiv.role = 'full-correct-response';\n containerDiv.appendChild(clone);\n\n clone.isFullCorrectResponse = true;\n\n this.parentElement?.insertBefore(containerDiv, this.nextSibling);\n await clone.updateComplete;\n\n clone.response = Array.isArray(responseVariable.correctResponse)\n ? ([...responseVariable.correctResponse] as string[])\n : (responseVariable.correctResponse as string);\n }\n\n protected toggleInternalCorrectResponse(show: boolean): void {\n const responseVariable = this.responseVariable;\n\n this.correctResponse = show\n ? responseVariable?.correctResponse\n : responseVariable?.cardinality === 'single'\n ? ''\n : [];\n }\n\n public toggleCandidateCorrection(show: boolean): void {\n const responseVariable = this.responseVariable;\n if (!responseVariable) return;\n\n this._internals.states.delete('candidate-correct');\n this._internals.states.delete('candidate-partially-correct');\n this._internals.states.delete('candidate-incorrect');\n\n if (!show) {\n return;\n }\n\n if (this.correctness === Correctness.Correct) {\n this._internals.states.add('candidate-correct');\n }\n if (this.correctness === Correctness.PartiallyCorrect) {\n this._internals.states.add('candidate-partially-correct');\n }\n if (this.correctness === Correctness.Incorrect) {\n this._internals.states.add('candidate-incorrect');\n }\n }\n\n constructor() {\n super();\n this._internals = this.attachInternals();\n }\n\n abstract validate(): boolean;\n\n get value(): string | null {\n return JSON.stringify(this.response);\n }\n\n set value(val: string | null) {\n this.response = val ? JSON.parse(val) : null;\n }\n\n abstract get response(): string | string[] | null;\n abstract set response(val: string | string[] | null);\n\n public reportValidity(): boolean {\n return this._internals.reportValidity();\n }\n\n public reset(): void {\n this.response = null;\n }\n\n // attributeChangedCallback(name: string, _old: string | null, value: string | null): void {\n // super.attributeChangedCallback(name, _old, value);\n // // changing attributes in lit is not a thing, they are defined in the QTI XML and will never change\n // // except in storybook where we can change the value of the attribute\n // // this can make the internal state out of sync with the attribute\n // // so we reset the value to null to force the internal state to be reset\n // const attributeNamesToExclude = ['style', 'class'];\n // if (!attributeNamesToExclude.includes(name)) {\n // this.reset();\n // }\n // }\n\n public override connectedCallback(): void {\n super.connectedCallback();\n\n if (this.isFullCorrectResponse) {\n return;\n }\n\n this.dispatchEvent(\n new CustomEvent('qti-register-interaction', {\n bubbles: true,\n composed: true,\n cancelable: false,\n detail: {\n interactionElement: this,\n responseIdentifier: this.responseIdentifier\n }\n })\n );\n }\n\n public saveResponse(value: string | string[]): void {\n this.dispatchEvent(\n new CustomEvent('qti-interaction-response', {\n bubbles: true,\n composed: true,\n cancelable: false,\n detail: {\n responseIdentifier: this.responseIdentifier,\n response: Array.isArray(value) ? [...value] : value\n }\n })\n );\n }\n}\n"],"mappings":";;;;;;;;;;;AAAA,SAAS,UAAU,aAAa;AAChC,SAAS,kBAAkB;AAC3B,SAAS,eAAe;AAUjB,IAAK,cAAL,kBAAKA,iBAAL;AACL,EAAAA,aAAA,aAAU;AACV,EAAAA,aAAA,sBAAmB;AACnB,EAAAA,aAAA,eAAY;AAHF,SAAAA;AAAA,GAAA;AAML,IAAe,cAAf,cAAmC,WAAmC;AAAA,EAgK3E,cAAc;AACZ,UAAM;AAjJoC,oBAAW;AAEX,oBAAW;AAgJrD,SAAK,aAAa,KAAK,gBAAgB;AAAA,EACzC;AAAA,EA5JA;AAAA,SAAO,iBAAiB;AAAA;AAAA,EAGxB,IAAI,YAA8B;AAChC,WAAO,KAAK;AAAA,EACd;AAAA,EAWA,IAAI,wBAA2C;AAC7C,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,sBAAsB,KAAwB;AAChD,SAAK,yBAAyB;AAC9B,QAAI,KAAK;AACP,WAAK,WAAW;AAChB,WAAK,aAAa,uBAAuB,KAAK,qBAAqB,KAAK;AAAA,IAC1E;AAAA,EACF;AAAA,EAMA,IAAI,kBAA+C;AACjD,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,gBAAgB,KAAkC;AACpD,SAAK,mBAAmB;AAAA,EAC1B;AAAA,EAEA,IAAI,cAA4C;AAC9C,UAAM,mBAAmB,KAAK;AAC9B,QAAI,CAAC,oBAAoB,iBAAiB,oBAAoB,KAAM,QAAO;AAE3E,WAAO,iBAAiB,oBAAoB,iBAAiB,QAAQ,0BAAsB;AAAA,EAC7F;AAAA,EAEA,IAAI,WAAoB;AACtB,WAAO;AAAA,EACT;AAAA,EAEA,IAAI,mBAAiD;AAEnD,UAAM,oBAAoB,KAAK,SAAS,UAAU,OAAO,OAAK,EAAE,SAAS,UAAU;AAGnF,UAAM,qBAAqB,KAAK,aAAa,qBAAqB;AAGlE,WAAO,kBAAkB,KAAK,OAAK,EAAE,eAAe,kBAAkB;AAAA,EACxE;AAAA,EAEO,sBAAsB,MAAqB;AAChD,UAAM,sBAAsB,MAAM,eAAe,uBAAuB;AAExE,QAAI,wBAAwB,QAAQ;AAClC,WAAK,0BAA0B,IAAI;AAAA,IACrC,OAAO;AACL,WAAK,8BAA8B,IAAI;AAAA,IACzC;AAAA,EACF;AAAA,EAEA,MAAgB,0BAA0B,MAA8B;AACtE,UAAM,cAAc,KAAK;AACzB,UAAM,mCACJ,uBAAuB,kBAAkB,aAAa,UAAU,SAAS,uBAAuB;AAClG,UAAM,mBAAmB,KAAK;AAE9B,QAAI,CAAC,kBAAkB;AACrB;AAAA,IACF;AAEA,UAAM,0BAA0B,SAAS,MAAM,eAAe,yCAAyC,SAAS,KAAK,gBAAgB;AAErI,QAAI,CAAC,yBAAyB;AAC5B,UAAI,CAAC,kCAAkC;AACrC;AAAA,MACF;AAEA,WAAK,eAAe,YAAY,WAAW;AAAA,IAC7C;AAEA,QAAI,kCAAkC;AACpC;AAAA,IACF;AAIA,UAAM,QAAQ,KAAK,UAAU,IAAI;AAEjC,UAAM,eAAe,SAAS,cAAc,KAAK;AACjD,iBAAa,UAAU,IAAI,uBAAuB;AAClD,QAAI,KAAK,UAAU;AACjB,mBAAa,UAAU,IAAI,8BAA8B;AAAA,IAC3D,OAAO;AACL,mBAAa,UAAU,IAAI,6BAA6B;AAAA,IAC1D;AACA,iBAAa,OAAO;AACpB,iBAAa,YAAY,KAAK;AAE9B,UAAM,wBAAwB;AAE9B,SAAK,eAAe,aAAa,cAAc,KAAK,WAAW;AAC/D,UAAM,MAAM;AAEZ,UAAM,WAAW,MAAM,QAAQ,iBAAiB,eAAe,IAC1D,CAAC,GAAG,iBAAiB,eAAe,IACpC,iBAAiB;AAAA,EACxB;AAAA,EAEU,8BAA8B,MAAqB;AAC3D,UAAM,mBAAmB,KAAK;AAE9B,SAAK,kBAAkB,OACnB,kBAAkB,kBAClB,kBAAkB,gBAAgB,WAChC,KACA,CAAC;AAAA,EACT;AAAA,EAEO,0BAA0B,MAAqB;AACpD,UAAM,mBAAmB,KAAK;AAC9B,QAAI,CAAC,iBAAkB;AAEvB,SAAK,WAAW,OAAO,OAAO,mBAAmB;AACjD,SAAK,WAAW,OAAO,OAAO,6BAA6B;AAC3D,SAAK,WAAW,OAAO,OAAO,qBAAqB;AAEnD,QAAI,CAAC,MAAM;AACT;AAAA,IACF;AAEA,QAAI,KAAK,gBAAgB,yBAAqB;AAC5C,WAAK,WAAW,OAAO,IAAI,mBAAmB;AAAA,IAChD;AACA,QAAI,KAAK,gBAAgB,4CAA8B;AACrD,WAAK,WAAW,OAAO,IAAI,6BAA6B;AAAA,IAC1D;AACA,QAAI,KAAK,gBAAgB,6BAAuB;AAC9C,WAAK,WAAW,OAAO,IAAI,qBAAqB;AAAA,IAClD;AAAA,EACF;AAAA,EASA,IAAI,QAAuB;AACzB,WAAO,KAAK,UAAU,KAAK,QAAQ;AAAA,EACrC;AAAA,EAEA,IAAI,MAAM,KAAoB;AAC5B,SAAK,WAAW,MAAM,KAAK,MAAM,GAAG,IAAI;AAAA,EAC1C;AAAA,EAKO,iBAA0B;AAC/B,WAAO,KAAK,WAAW,eAAe;AAAA,EACxC;AAAA,EAEO,QAAc;AACnB,SAAK,WAAW;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcgB,oBAA0B;AACxC,UAAM,kBAAkB;AAExB,QAAI,KAAK,uBAAuB;AAC9B;AAAA,IACF;AAEA,SAAK;AAAA,MACH,IAAI,YAAY,4BAA4B;AAAA,QAC1C,SAAS;AAAA,QACT,UAAU;AAAA,QACV,YAAY;AAAA,QACZ,QAAQ;AAAA,UACN,oBAAoB;AAAA,UACpB,oBAAoB,KAAK;AAAA,QAC3B;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEO,aAAa,OAAgC;AAClD,SAAK;AAAA,MACH,IAAI,YAAY,4BAA4B;AAAA,QAC1C,SAAS;AAAA,QACT,UAAU;AAAA,QACV,YAAY;AAAA,QACZ,QAAQ;AAAA,UACN,oBAAoB,KAAK;AAAA,UACzB,UAAU,MAAM,QAAQ,KAAK,IAAI,CAAC,GAAG,KAAK,IAAI;AAAA,QAChD;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AACF;AArOU;AAAA,EADP,QAAQ,EAAE,SAAS,aAAa,WAAW,KAAK,CAAC;AAAA,GAD9B,YAEZ;AAGE;AAAA,EADT,QAAQ,EAAE,SAAS,eAAe,WAAW,KAAK,CAAC;AAAA,GAJhC,YAKV;AASoD;AAAA,EAA7D,SAAS,EAAE,MAAM,QAAQ,WAAW,sBAAsB,CAAC;AAAA,GAdxC,YAc0C;AAElB;AAAA,EAA3C,SAAS,EAAE,SAAS,MAAM,MAAM,QAAQ,CAAC;AAAA,GAhBtB,YAgBwB;AAEA;AAAA,EAA3C,SAAS,EAAE,SAAS,MAAM,MAAM,QAAQ,CAAC;AAAA,GAlBtB,YAkBwB;AAGlC;AAAA,EADT,MAAM;AAAA,GApBa,YAqBV;AAgBA;AAAA,EADT,MAAM;AAAA,GApCa,YAqCV;","names":["Correctness"]}
@@ -21,13 +21,13 @@ import {
21
21
  } from "./chunk-CJADUWEC.js";
22
22
  import {
23
23
  Interaction
24
- } from "./chunk-HFAUM56X.js";
24
+ } from "./chunk-P4QBOVQ2.js";
25
25
  import {
26
26
  itemContext
27
27
  } from "./chunk-NJNQOQUU.js";
28
28
  import {
29
29
  configContext
30
- } from "./chunk-ERYHQVOT.js";
30
+ } from "./chunk-BHJSX3Q6.js";
31
31
  import {
32
32
  itemContextVariables
33
33
  } from "./chunk-JQ6HWGRY.js";
@@ -6267,9 +6267,12 @@ var QtiTextEntryInteraction = class extends Interaction {
6267
6267
  }
6268
6268
  get correctness() {
6269
6269
  const responseVariable = this.responseVariable;
6270
- if (!responseVariable || responseVariable.value === null) {
6270
+ if (!responseVariable) {
6271
6271
  return null;
6272
6272
  }
6273
+ if (responseVariable.value === null) {
6274
+ return "incorrect" /* Incorrect */;
6275
+ }
6273
6276
  if (responseVariable.mapping) {
6274
6277
  const maxScore = responseVariable.mapping.mapEntries.reduce(
6275
6278
  (currentMax, mapEntry) => Math.max(mapEntry.mappedValue, currentMax),
@@ -8813,4 +8816,4 @@ export {
8813
8816
  QtiOutcomeDeclaration,
8814
8817
  QtiResponseDeclaration
8815
8818
  };
8816
- //# sourceMappingURL=chunk-7YO5JFT3.js.map
8819
+ //# sourceMappingURL=chunk-TWFYYDV7.js.map