@citolab/qti-components 7.14.1 → 7.14.3
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/cdn/index.global.js +1 -1
- package/cdn/index.js +86 -78
- package/custom-elements.json +427 -5
- package/dist/chunks/{chunk-YD7FVKDP.js → chunk-AGV5GOTF.js} +3 -5
- package/dist/chunks/chunk-AGV5GOTF.js.map +1 -0
- package/dist/chunks/{chunk-TISKSGJE.js → chunk-C4ELTNV7.js} +77 -18
- package/dist/chunks/chunk-C4ELTNV7.js.map +1 -0
- package/dist/chunks/{chunk-7567ZPN6.js → chunk-DGBI4IU5.js} +2 -2
- package/dist/chunks/{chunk-XEKFVRIO.js → chunk-E4GR4K26.js} +3 -4
- package/dist/chunks/{chunk-XEKFVRIO.js.map → chunk-E4GR4K26.js.map} +1 -1
- package/dist/chunks/{chunk-PT5ASWGQ.js → chunk-TN75CWLX.js} +9 -1
- package/dist/chunks/{chunk-PT5ASWGQ.js.map → chunk-TN75CWLX.js.map} +1 -1
- package/dist/exports/qti-test.d.ts +2 -2
- package/dist/index.d.ts +2 -3
- package/dist/index.js +16 -14
- package/dist/index.js.map +1 -1
- package/dist/item.css +8 -0
- package/dist/qti-components/index.d.ts +5 -3
- package/dist/qti-components/index.js +4 -2
- package/dist/qti-components-jsx.d.ts +23 -22
- package/dist/qti-item/index.js +2 -2
- package/dist/{qti-modal-feedback-PKbhO-3w.d.ts → qti-modal-feedback-Cp3CHVKw.d.ts} +1 -1
- package/dist/qti-test/index.d.ts +5 -6
- package/dist/qti-test/index.js +3 -3
- package/dist/{qti-test-Db7oNIWY.d.ts → qti-test-mmY8zNIj.d.ts} +1 -1
- package/dist/vscode.html-custom-data.json +7 -7
- package/package.json +10 -10
- package/dist/chunks/chunk-TISKSGJE.js.map +0 -1
- package/dist/chunks/chunk-YD7FVKDP.js.map +0 -1
- /package/dist/chunks/{chunk-7567ZPN6.js.map → chunk-DGBI4IU5.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/lib/qti-components/qti-feedback/qti-feedback.ts","../../src/lib/qti-components/internal/utils.ts","../../src/lib/qti-components/qti-feedback/qti-modal-feedback/qti-modal-feedback.ts","../../src/lib/decorators/live-query.ts","../../src/lib/decorators/prop-internal-state.ts"],"sourcesContent":["import { consume } from '@lit/context';\nimport { LitElement } from 'lit';\nimport { property, state } from 'lit/decorators.js';\n\nimport { IsNullOrUndefined } from '../internal/utils';\nimport { itemContext } from '../../exports/qti-assessment-item.context';\n\nimport type { ItemContext } from '../../exports/item.context';\n\nexport abstract class QtiFeedback extends LitElement {\n @property({ type: String, attribute: 'show-hide' })\n protected showHide: string;\n\n @property({ type: String, attribute: 'outcome-identifier' })\n public outcomeIdentifier: string;\n\n @property({ type: String })\n protected identifier: string;\n\n @property({ type: String, attribute: false })\n public showStatus: string;\n\n @consume({ context: itemContext, subscribe: true })\n @state()\n private _context?: ItemContext;\n\n public override connectedCallback() {\n super.connectedCallback();\n this.dispatchEvent(\n new CustomEvent<QtiFeedback>('qti-register-feedback', {\n bubbles: true,\n composed: true,\n detail: this\n })\n );\n }\n\n public checkShowFeedback(outcomeIdentifier: string) {\n const outcomeVariable = this._context.variables.find(v => v.identifier === outcomeIdentifier) || null;\n if (this.outcomeIdentifier !== outcomeIdentifier || !outcomeVariable) return;\n let isFound = false;\n if (Array.isArray(outcomeVariable.value)) {\n isFound = outcomeVariable.value.includes(this.identifier);\n } else {\n isFound =\n (!IsNullOrUndefined(this.identifier) &&\n !IsNullOrUndefined(outcomeVariable?.value) &&\n this.identifier === outcomeVariable.value) ||\n false;\n }\n\n this.showFeedback(isFound);\n }\n\n private showFeedback(value: boolean) {\n this.showStatus = (value && this.showHide === 'show') || (!value && this.showHide === 'hide') ? 'on' : 'off';\n }\n}\n","export const decimalSeparator = () => {\n return new Intl.NumberFormat().format(0.1).replace(/\\d/g, '');\n};\n\nexport const convertNumberToUniversalFormat = (number: number | string) => {\n // check if type is string\n if (typeof number === 'string') {\n return number;\n }\n const dSep = decimalSeparator();\n if (dSep === '.') {\n return number.toLocaleString();\n } else {\n return number.toString().replace('.', '').replace(dSep, '.');\n }\n};\n\nexport function IsNullOrUndefined(value: unknown) {\n return value === null || value === undefined;\n}\n\nexport function removeDoubleSlashes(str: string) {\n const singleForwardSlashes = str\n .replace(/([^:]\\/)\\/+/g, '$1')\n .replace(/\\/\\//g, '/')\n .replace('http:/', 'http://')\n .replace('https:/', 'https://');\n return singleForwardSlashes;\n}\n","import { css, html } from 'lit';\nimport { customElement } from 'lit/decorators.js';\n\nimport { QtiFeedback } from '../qti-feedback';\n\n@customElement('qti-modal-feedback')\nexport class QtiModalFeedback extends QtiFeedback {\n static override styles = css`\n .qti-dialog {\n background: var(--qti-bg);\n border: var(--qti-border-thickness) var(--qti-border-style) var(--qti-border-color);\n border-radius: var(--qti-border-radius);\n padding: var(--qti-padding-vertical) var(--qti-padding-horizontal);\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n z-index: 1000;\n width: auto;\n max-width: 90%;\n }\n\n .button {\n border-radius: var(--qti-border-radius);\n padding: var(--qti-padding-vertical) var(--qti-padding-horizontal);\n background-color: var(--qti-bg-active);\n border: var(--qti-border-active);\n cursor: pointer;\n position: relative;\n display: inline-block;\n }\n\n .button:hover {\n background-color: var(--qti-hover-bg);\n }\n\n .button:disabled {\n background-color: var(--qti-disabled-bg);\n color: var(--qti-disabled-color);\n cursor: not-allowed;\n }\n\n .button:focus {\n outline: var(--qti-focus-border-width) solid var(--qti-focus-color);\n }\n `;\n\n override render() {\n return html`\n <dialog class=\"qti-dialog\" part=\"feedback\" ?open=\"${this.showStatus === 'on'}\">\n <slot></slot>\n <div style=\"margin-top: var(--qti-gap-size); text-align: center;\">\n <button class=\"button close-button\" @click=\"${this.closeFeedback}\">Close</button>\n </div>\n </dialog>\n `;\n }\n\n openFeedback() {\n const dialog = this.shadowRoot?.querySelector('dialog') as HTMLDialogElement | null;\n if (dialog && !dialog.open) {\n dialog.showModal();\n }\n }\n\n closeFeedback() {\n const dialog = this.shadowRoot?.querySelector('dialog') as HTMLDialogElement | null;\n if (dialog && dialog.open) {\n dialog.close();\n this.showStatus = 'off';\n }\n }\n\n public connectedCallback(): void {\n super.connectedCallback();\n if (this.showStatus === 'on') {\n this.openFeedback();\n }\n }\n\n protected updated(changedProperties: Map<string | number | symbol, unknown>): void {\n if (changedProperties.has('showStatus')) {\n if (this.showStatus === 'on') {\n this.openFeedback();\n } else {\n this.closeFeedback();\n }\n }\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'qti-modal-feedback': QtiModalFeedback;\n }\n}\n","import type { LitElement } from 'lit';\n\ntype LiveQueryHandler = (added: Element[], removed: Element[]) => void;\ntype LiveQueryHandlerKeys<T extends object> = {\n [K in keyof T]-?: T[K] extends LiveQueryHandler ? K : never;\n}[keyof T];\n\ninterface LiveQueryOptions {\n /**\n * If true, will only start watching after the initial update/render\n */\n waitUntilFirstUpdate?: boolean;\n}\n\nexport function liveQuery(querySelector: string, options?: LiveQueryOptions) {\n return <ElemClass extends LitElement>(proto: ElemClass, decoratedFnName: LiveQueryHandlerKeys<ElemClass>): void => {\n const { connectedCallback, disconnectedCallback } = proto;\n\n proto.connectedCallback = function (this: ElemClass) {\n connectedCallback.call(this);\n\n const handler = this[decoratedFnName] as unknown as LiveQueryHandler;\n\n const callback = (mutationList: MutationRecord[]) => {\n const added: Element[] = [];\n const removed: Element[] = [];\n\n for (const m of mutationList) {\n if (m.type !== 'childList') continue;\n\n m.addedNodes.forEach(n => {\n if (n.nodeType !== 1) return;\n const el = n as Element;\n if (el.matches?.(querySelector)) added.push(el);\n added.push(...(el.querySelectorAll?.(querySelector) ?? []));\n });\n\n m.removedNodes.forEach(n => {\n if (n.nodeType !== 1) return;\n const el = n as Element;\n if (el.matches?.(querySelector)) removed.push(el);\n removed.push(...(el.querySelectorAll?.(querySelector) ?? []));\n });\n }\n\n // deduplicate added and removed (might be multiples since we observe both light and shadow DOM)\n const dedupe = (arr: Element[]) => Array.from(new Set(arr));\n const A = dedupe(added);\n const R = dedupe(removed);\n\n if (A.length || R.length) {\n handler.call(this, A, R);\n }\n };\n\n // observe both light and shadow DOM\n const obsLight = new MutationObserver(callback);\n obsLight.observe(this, { childList: true, subtree: true });\n\n const obsShadow = this.shadowRoot ? new MutationObserver(callback) : null;\n obsShadow?.observe(this.shadowRoot, { childList: true, subtree: true });\n\n (this as any).__lqObservers = [obsLight, obsShadow].filter((o): o is MutationObserver => !!o);\n\n const fireInitial = async () => {\n if (options?.waitUntilFirstUpdate && 'updateComplete' in this) {\n await (this as any).updateComplete;\n }\n const initial = [\n ...this.querySelectorAll(querySelector),\n ...(this.shadowRoot?.querySelectorAll(querySelector) ?? [])\n ] as Element[];\n if (initial.length) handler.call(this, initial, []);\n };\n\n void fireInitial();\n };\n\n proto.disconnectedCallback = function (this: ElemClass) {\n disconnectedCallback.call(this);\n (this as any).__lqObservers?.forEach((o: MutationObserver) => o.disconnect());\n (this as any).__lqObservers = undefined;\n };\n };\n}\n","import { property } from 'lit/decorators.js';\n\nimport type { ReactiveElement } from 'lit';\nimport type { PropertyDeclaration } from 'lit';\n\n// Extended decorator options\ninterface InternalStateOptions extends PropertyDeclaration {\n aria?: string; // Corresponding ARIA attribute, e.g., 'aria-disabled'\n}\n\nexport function propInternalState(options: InternalStateOptions) {\n return (protoOrDescriptor: any, name: string) => {\n // Apply the default Lit `@property` decorator\n property(options)(protoOrDescriptor, name);\n\n // Intercept the property descriptor to enhance functionality\n const key = `__${name}`; // Internal backing field\n\n Object.defineProperty(protoOrDescriptor, name, {\n get() {\n return this[key];\n },\n set(value: any) {\n const oldValue = this[key];\n this[key] = value;\n\n // Trigger updates if value changes\n if (oldValue !== value) {\n // Update internals state\n if (this._internals?.states) {\n const stateName = name.toLowerCase();\n if (value) {\n this._internals.states.add(`--${stateName}`);\n } else {\n this._internals.states.delete(`--${stateName}`);\n }\n }\n\n // Update ARIA attributes if specified\n if (options.aria && this._internals) {\n const ariaAttribute = options.aria;\n if (value) {\n this._internals[ariaAttribute] = 'true';\n } else {\n this._internals[ariaAttribute] = null;\n }\n }\n\n // Request an update\n (this as ReactiveElement).requestUpdate(name, oldValue);\n }\n },\n configurable: true,\n enumerable: true\n });\n };\n}\n"],"mappings":"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","names":["property"]}
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
convertNumberToUniversalFormat,
|
|
4
4
|
liveQuery,
|
|
5
5
|
removeDoubleSlashes
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-AGV5GOTF.js";
|
|
7
7
|
import {
|
|
8
8
|
watch
|
|
9
9
|
} from "./chunk-ELDMXTUQ.js";
|
|
@@ -755,6 +755,8 @@ var DragDropInteractionMixin = (superClass, draggablesSelector, droppablesSelect
|
|
|
755
755
|
// Minimum pixel movement to start dragging
|
|
756
756
|
this.DRAG_CLONE_OPACITY = 1;
|
|
757
757
|
// Opacity of the drag clone element
|
|
758
|
+
this.MAX_DRAGGABLE_WIDTH = 600;
|
|
759
|
+
// Maximum width of a draggable element
|
|
758
760
|
this.dataTransfer = {
|
|
759
761
|
data: {},
|
|
760
762
|
setData(type, val) {
|
|
@@ -924,33 +926,50 @@ var DragDropInteractionMixin = (superClass, draggablesSelector, droppablesSelect
|
|
|
924
926
|
await this.updateComplete;
|
|
925
927
|
if (this.isMatchTabular()) return;
|
|
926
928
|
const draggables = this.querySelectorAll(draggablesSelector);
|
|
927
|
-
const droppables = Array.from(this.querySelectorAll(droppablesSelector)).map((d) => d);
|
|
928
|
-
let maxHeight = 0;
|
|
929
|
-
let maxWidth = 0;
|
|
930
|
-
draggables.forEach((draggable) => {
|
|
931
|
-
const rect = draggable.getBoundingClientRect();
|
|
932
|
-
maxHeight = Math.max(maxHeight, rect.height);
|
|
933
|
-
maxWidth = Math.max(maxWidth, rect.width);
|
|
934
|
-
});
|
|
935
929
|
const dragContainer = this.querySelector(dragContainersSelector) || this.shadowRoot?.querySelector(dragContainersSelector);
|
|
930
|
+
const droppables = this.querySelectorAll(droppablesSelector);
|
|
936
931
|
const dropContainer = droppables[0]?.parentElement;
|
|
932
|
+
const maxWidth = this.determineMaxWidth(dragContainer, dropContainer);
|
|
933
|
+
let maxDraggableHeight = 0;
|
|
934
|
+
let maxDraggableWidth = 0;
|
|
935
|
+
for (const draggable of draggables) {
|
|
936
|
+
draggable.style.maxWidth = maxWidth + "px";
|
|
937
|
+
const { width, height } = await this.measureIntrinsicSize(draggable);
|
|
938
|
+
maxDraggableHeight = Math.max(maxDraggableHeight, height);
|
|
939
|
+
maxDraggableWidth = Math.max(maxDraggableWidth, width);
|
|
940
|
+
}
|
|
937
941
|
if (dropContainer) {
|
|
938
|
-
dropContainer.style.gridTemplateColumns = `repeat(auto-fit, minmax(calc(${maxWidth}px + 2 * var(--qti-dropzone-padding)), 1fr))`;
|
|
942
|
+
dropContainer.style.gridTemplateColumns = `repeat(auto-fit, minmax(calc(min(${maxWidth}px,${maxDraggableWidth}px + 2 * var(--qti-dropzone-padding))), 1fr))`;
|
|
939
943
|
}
|
|
940
944
|
if (dragContainer) {
|
|
941
|
-
dragContainer.style.minHeight = `${
|
|
942
|
-
dragContainer.style.minWidth = `${maxWidth}px`;
|
|
945
|
+
dragContainer.style.minHeight = `${maxDraggableHeight}px`;
|
|
943
946
|
}
|
|
944
947
|
for (const droppable of droppables) {
|
|
945
|
-
droppable.style.minHeight = `${
|
|
946
|
-
droppable.style.minWidth = `${
|
|
948
|
+
droppable.style.minHeight = `${maxDraggableHeight}px`;
|
|
949
|
+
droppable.style.minWidth = `${maxDraggableWidth}px`;
|
|
947
950
|
const dropSlot = droppable.shadowRoot?.querySelector('slot[part="dropslot"]');
|
|
948
951
|
if (dropSlot) {
|
|
949
|
-
dropSlot.style.minHeight = `${
|
|
950
|
-
dropSlot.style.minWidth = `${maxWidth}px`;
|
|
952
|
+
dropSlot.style.minHeight = `${maxDraggableHeight}px`;
|
|
951
953
|
}
|
|
952
954
|
}
|
|
953
955
|
}
|
|
956
|
+
determineMaxWidth(dragContainer, dropContainer) {
|
|
957
|
+
const referenceContainer = dropContainer ?? dragContainer;
|
|
958
|
+
if (!referenceContainer || referenceContainer.clientWidth == 0) {
|
|
959
|
+
return this.MAX_DRAGGABLE_WIDTH;
|
|
960
|
+
}
|
|
961
|
+
const styles = window.getComputedStyle(referenceContainer);
|
|
962
|
+
const paddingLeft = parseFloat(styles.paddingLeft);
|
|
963
|
+
const paddingRight = parseFloat(styles.paddingRight);
|
|
964
|
+
return Math.min(this.MAX_DRAGGABLE_WIDTH, referenceContainer.clientWidth - paddingLeft - paddingRight);
|
|
965
|
+
}
|
|
966
|
+
async measureIntrinsicSize(el) {
|
|
967
|
+
const origPosition = el.style.position;
|
|
968
|
+
el.style.position = "fixed";
|
|
969
|
+
const rect = el.getBoundingClientRect();
|
|
970
|
+
el.style.position = origPosition;
|
|
971
|
+
return { width: rect.width, height: rect.height };
|
|
972
|
+
}
|
|
954
973
|
activateDroppables(target) {
|
|
955
974
|
if (this.isMatchTabular()) return;
|
|
956
975
|
const dragContainers = this.dragContainers;
|
|
@@ -1696,7 +1715,7 @@ var ChoicesMixin = (superClass, selector) => {
|
|
|
1696
1715
|
this._setChoiceChecked(choice, false);
|
|
1697
1716
|
}
|
|
1698
1717
|
});
|
|
1699
|
-
} else if (this._configContext?.disableAfterIfMaxChoicesReached) {
|
|
1718
|
+
} else if (this.maxChoices !== 0 && this._configContext?.disableAfterIfMaxChoicesReached) {
|
|
1700
1719
|
const selectedChoices = this._choiceElements.filter((choice) => this._getChoiceChecked(choice));
|
|
1701
1720
|
if (selectedChoices.length >= this.maxChoices) {
|
|
1702
1721
|
this._choiceElements.forEach((choice) => {
|
|
@@ -2469,6 +2488,46 @@ var QtiGapMatchInteraction = class extends DragDropInteractionMixin(
|
|
|
2469
2488
|
});
|
|
2470
2489
|
}
|
|
2471
2490
|
}
|
|
2491
|
+
getMatches(responseVariable) {
|
|
2492
|
+
if (!responseVariable.correctResponse) {
|
|
2493
|
+
return [];
|
|
2494
|
+
}
|
|
2495
|
+
const correctResponse = Array.isArray(responseVariable.correctResponse) ? responseVariable.correctResponse : [responseVariable.correctResponse];
|
|
2496
|
+
const matches = [];
|
|
2497
|
+
if (correctResponse) {
|
|
2498
|
+
correctResponse.forEach((x) => {
|
|
2499
|
+
const split = x.split(" ");
|
|
2500
|
+
matches.push({ source: split[0], target: split[1] });
|
|
2501
|
+
});
|
|
2502
|
+
}
|
|
2503
|
+
return matches;
|
|
2504
|
+
}
|
|
2505
|
+
toggleCandidateCorrection(show) {
|
|
2506
|
+
const responseVariable = this.responseVariable;
|
|
2507
|
+
if (!responseVariable?.correctResponse) {
|
|
2508
|
+
return;
|
|
2509
|
+
}
|
|
2510
|
+
const matches = this.getMatches(responseVariable);
|
|
2511
|
+
const targetChoices = Array.from(this.querySelectorAll("qti-gap"));
|
|
2512
|
+
targetChoices.forEach((targetChoice) => {
|
|
2513
|
+
const targetId = targetChoice.getAttribute("identifier");
|
|
2514
|
+
const targetMatches = matches.filter((m) => m.target === targetId);
|
|
2515
|
+
const selectedChoices = targetChoice.querySelectorAll(`qti-gap-text`);
|
|
2516
|
+
selectedChoices.forEach((selectedChoice) => {
|
|
2517
|
+
selectedChoice.internals.states.delete("candidate-correct");
|
|
2518
|
+
selectedChoice.internals.states.delete("candidate-incorrect");
|
|
2519
|
+
if (!show) {
|
|
2520
|
+
return;
|
|
2521
|
+
}
|
|
2522
|
+
const isCorrect = targetMatches.find((m) => m.source === selectedChoice.identifier)?.source !== void 0;
|
|
2523
|
+
if (isCorrect) {
|
|
2524
|
+
selectedChoice.internals.states.add("candidate-correct");
|
|
2525
|
+
} else {
|
|
2526
|
+
selectedChoice.internals.states.add("candidate-incorrect");
|
|
2527
|
+
}
|
|
2528
|
+
});
|
|
2529
|
+
});
|
|
2530
|
+
}
|
|
2472
2531
|
};
|
|
2473
2532
|
QtiGapMatchInteraction.styles = qti_gap_match_interaction_styles_default;
|
|
2474
2533
|
QtiGapMatchInteraction = __decorateClass([
|
|
@@ -8827,4 +8886,4 @@ export {
|
|
|
8827
8886
|
QtiOutcomeDeclaration,
|
|
8828
8887
|
QtiResponseDeclaration
|
|
8829
8888
|
};
|
|
8830
|
-
//# sourceMappingURL=chunk-
|
|
8889
|
+
//# sourceMappingURL=chunk-C4ELTNV7.js.map
|