@qti-editor/interaction-choice 0.1.0 → 0.2.1
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/dist/components/qti-choice-interaction/commands/convert-selection-to-choice.commands.d.ts.map +1 -1
- package/dist/components/qti-choice-interaction/commands/convert-selection-to-choice.commands.js +108 -53
- package/dist/components/qti-choice-interaction/commands/insert-choice-interaction.commands.d.ts.map +1 -1
- package/dist/components/qti-choice-interaction/commands/insert-choice-interaction.commands.js +7 -5
- package/dist/components/qti-choice-interaction/qti-choice-interaction.d.ts.map +1 -1
- package/dist/components/qti-choice-interaction/qti-choice-interaction.js +14 -2
- package/package.json +13 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convert-selection-to-choice.commands.d.ts","sourceRoot":"","sources":["../../../../src/components/qti-choice-interaction/commands/convert-selection-to-choice.commands.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"convert-selection-to-choice.commands.d.ts","sourceRoot":"","sources":["../../../../src/components/qti-choice-interaction/commands/convert-selection-to-choice.commands.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AA8LnD,wBAAgB,qCAAqC,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAwB/E;AAED,wBAAgB,kCAAkC,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAiD5E"}
|
package/dist/components/qti-choice-interaction/commands/convert-selection-to-choice.commands.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { translateQti } from '@qti-editor/interaction-shared';
|
|
1
2
|
function isFlatList(listNode, listType) {
|
|
2
3
|
let hasNestedList = false;
|
|
3
4
|
listNode.descendants((node, pos) => {
|
|
@@ -9,37 +10,46 @@ function isFlatList(listNode, listType) {
|
|
|
9
10
|
});
|
|
10
11
|
return !hasNestedList;
|
|
11
12
|
}
|
|
12
|
-
function
|
|
13
|
+
function hasOnlyTextInlineContent(node) {
|
|
14
|
+
for (let i = 0; i < node.childCount; i++) {
|
|
15
|
+
if (!node.child(i).isText)
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
function isPlainTextParagraph(node, schema) {
|
|
21
|
+
const paragraphType = schema.nodes.paragraph;
|
|
22
|
+
return Boolean(paragraphType && node.type === paragraphType && hasOnlyTextInlineContent(node));
|
|
23
|
+
}
|
|
24
|
+
function isConvertibleList(node, schema) {
|
|
13
25
|
const paragraphType = schema.nodes.paragraph;
|
|
14
26
|
const listType = schema.nodes.list;
|
|
15
|
-
if (paragraphType
|
|
16
|
-
return
|
|
27
|
+
if (!paragraphType || !listType || node.type !== listType) {
|
|
28
|
+
return false;
|
|
17
29
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
30
|
+
const listKind = node.attrs?.kind;
|
|
31
|
+
if (!['bullet', 'ordered'].includes(listKind))
|
|
32
|
+
return false;
|
|
33
|
+
if (!isFlatList(node, listType))
|
|
34
|
+
return false;
|
|
35
|
+
for (let i = 0; i < node.childCount; i += 1) {
|
|
36
|
+
const child = node.child(i);
|
|
37
|
+
if (child.type !== paragraphType || !hasOnlyTextInlineContent(child)) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
25
40
|
}
|
|
26
|
-
return
|
|
41
|
+
return node.childCount > 0;
|
|
27
42
|
}
|
|
28
|
-
function
|
|
43
|
+
function getSelectedRootBlocks(view) {
|
|
29
44
|
const { state } = view;
|
|
30
45
|
const { selection } = state;
|
|
31
|
-
const schema = state.schema;
|
|
32
46
|
const blocks = [];
|
|
33
47
|
const seenPositions = new Set();
|
|
34
|
-
const
|
|
35
|
-
if (seenPositions.has(start))
|
|
36
|
-
return;
|
|
37
|
-
const kind = isConvertibleRootBlock(node, schema);
|
|
38
|
-
if (!kind)
|
|
48
|
+
const addBlock = (node, start) => {
|
|
49
|
+
if (seenPositions.has(start) || !node.isBlock)
|
|
39
50
|
return;
|
|
40
51
|
seenPositions.add(start);
|
|
41
52
|
blocks.push({
|
|
42
|
-
kind,
|
|
43
53
|
pos: start,
|
|
44
54
|
end: start + node.nodeSize,
|
|
45
55
|
node,
|
|
@@ -72,20 +82,16 @@ function getSelectedConvertibleBlocks(view) {
|
|
|
72
82
|
};
|
|
73
83
|
if (selection.empty) {
|
|
74
84
|
const rootBlock = getRootBlockAt(selection.from);
|
|
75
|
-
if (
|
|
76
|
-
|
|
77
|
-
addBlockIfConvertible(rootBlock.node, rootBlock.start);
|
|
85
|
+
if (rootBlock)
|
|
86
|
+
addBlock(rootBlock.node, rootBlock.start);
|
|
78
87
|
return blocks;
|
|
79
88
|
}
|
|
80
|
-
// Block-select plugin uses a custom "node-range" selection with explicit block ranges.
|
|
81
|
-
// Prefer those exact ranges to avoid text-range quirks across custom elements/shadow DOM.
|
|
82
89
|
const selectionJSON = selection.toJSON();
|
|
83
90
|
if (selectionJSON.type === 'node-range' && Array.isArray(selection.ranges)) {
|
|
84
91
|
for (const range of selection.ranges) {
|
|
85
92
|
const rootBlock = getRootBlockAt(range.$from.pos);
|
|
86
|
-
if (
|
|
87
|
-
|
|
88
|
-
addBlockIfConvertible(rootBlock.node, rootBlock.start);
|
|
93
|
+
if (rootBlock)
|
|
94
|
+
addBlock(rootBlock.node, rootBlock.start);
|
|
89
95
|
}
|
|
90
96
|
if (blocks.length > 0)
|
|
91
97
|
return blocks;
|
|
@@ -96,22 +102,65 @@ function getSelectedConvertibleBlocks(view) {
|
|
|
96
102
|
const intersectsSelection = end > selection.from && start < selection.to;
|
|
97
103
|
if (!intersectsSelection)
|
|
98
104
|
return;
|
|
99
|
-
|
|
105
|
+
addBlock(node, start);
|
|
100
106
|
});
|
|
101
107
|
return blocks;
|
|
102
108
|
}
|
|
103
|
-
function
|
|
104
|
-
if (
|
|
105
|
-
return
|
|
109
|
+
function buildConversionPlan(blocks, schema) {
|
|
110
|
+
if (blocks.length === 0)
|
|
111
|
+
return null;
|
|
112
|
+
// All-paragraph mode: first paragraph → prompt, rest → choices
|
|
113
|
+
if (blocks.every(b => isPlainTextParagraph(b.node, schema))) {
|
|
114
|
+
if (blocks.length < 2)
|
|
115
|
+
return null;
|
|
116
|
+
const [promptBlock, ...choiceBlocks] = blocks;
|
|
117
|
+
return {
|
|
118
|
+
promptText: promptBlock.node.textContent.trim() || null,
|
|
119
|
+
blocksToReplace: blocks,
|
|
120
|
+
choiceContents: choiceBlocks.map(b => b.node.content.size > 0 ? b.node.content : null),
|
|
121
|
+
};
|
|
106
122
|
}
|
|
107
|
-
|
|
108
|
-
|
|
123
|
+
// List mode: optional leading plain-text paragraphs as prompt, then list(s)
|
|
124
|
+
const promptBlocks = [];
|
|
125
|
+
const listBlocks = [];
|
|
126
|
+
let sawList = false;
|
|
127
|
+
for (const block of blocks) {
|
|
128
|
+
if (isPlainTextParagraph(block.node, schema)) {
|
|
129
|
+
if (sawList)
|
|
130
|
+
return null;
|
|
131
|
+
promptBlocks.push(block);
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
if (isConvertibleList(block.node, schema)) {
|
|
135
|
+
sawList = true;
|
|
136
|
+
listBlocks.push(block);
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
109
139
|
return null;
|
|
110
|
-
const firstChild = block.node.firstChild;
|
|
111
|
-
if (firstChild && firstChild.type === paragraphType) {
|
|
112
|
-
return firstChild.content;
|
|
113
140
|
}
|
|
114
|
-
|
|
141
|
+
if (listBlocks.length === 0)
|
|
142
|
+
return null;
|
|
143
|
+
const promptText = promptBlocks
|
|
144
|
+
.map(block => block.node.textContent.trim())
|
|
145
|
+
.filter(Boolean)
|
|
146
|
+
.join(' ')
|
|
147
|
+
.trim();
|
|
148
|
+
const paragraphType = schema.nodes.paragraph;
|
|
149
|
+
const choiceContents = listBlocks.flatMap(block => {
|
|
150
|
+
const contents = [];
|
|
151
|
+
for (let i = 0; i < block.node.childCount; i += 1) {
|
|
152
|
+
const child = block.node.child(i);
|
|
153
|
+
if (child.type !== paragraphType)
|
|
154
|
+
continue;
|
|
155
|
+
contents.push(child.content.size > 0 ? child.content : null);
|
|
156
|
+
}
|
|
157
|
+
return contents;
|
|
158
|
+
});
|
|
159
|
+
return {
|
|
160
|
+
promptText: promptText || null,
|
|
161
|
+
blocksToReplace: [...promptBlocks, ...listBlocks],
|
|
162
|
+
choiceContents,
|
|
163
|
+
};
|
|
115
164
|
}
|
|
116
165
|
export function canConvertFlatListToChoiceInteraction(view) {
|
|
117
166
|
const { state } = view;
|
|
@@ -124,12 +173,16 @@ export function canConvertFlatListToChoiceInteraction(view) {
|
|
|
124
173
|
if (!interactionType || !promptType || !promptParagraphType || !choiceType || !choiceParagraphType) {
|
|
125
174
|
return false;
|
|
126
175
|
}
|
|
127
|
-
const
|
|
128
|
-
if (
|
|
176
|
+
const plan = buildConversionPlan(getSelectedRootBlocks(view), schema);
|
|
177
|
+
if (!plan)
|
|
178
|
+
return false;
|
|
179
|
+
const firstBlock = plan.blocksToReplace[0];
|
|
180
|
+
const lastBlock = plan.blocksToReplace[plan.blocksToReplace.length - 1];
|
|
181
|
+
const $from = state.doc.resolve(firstBlock.pos);
|
|
182
|
+
const $to = state.doc.resolve(lastBlock.end);
|
|
183
|
+
if ($from.parent !== $to.parent)
|
|
129
184
|
return false;
|
|
130
|
-
|
|
131
|
-
const $pos = state.doc.resolve(firstBlock.pos);
|
|
132
|
-
return $pos.parent.canReplaceWith($pos.index(), $pos.index() + 1, interactionType);
|
|
185
|
+
return $from.parent.canReplaceWith($from.index(), $to.index(), interactionType);
|
|
133
186
|
}
|
|
134
187
|
export function convertFlatListToChoiceInteraction(view) {
|
|
135
188
|
const { state } = view;
|
|
@@ -142,24 +195,26 @@ export function convertFlatListToChoiceInteraction(view) {
|
|
|
142
195
|
if (!interactionType || !promptType || !promptParagraphType || !choiceType || !choiceParagraphType) {
|
|
143
196
|
return false;
|
|
144
197
|
}
|
|
145
|
-
const
|
|
146
|
-
if (
|
|
198
|
+
const plan = buildConversionPlan(getSelectedRootBlocks(view), schema);
|
|
199
|
+
if (!plan)
|
|
147
200
|
return false;
|
|
148
|
-
const
|
|
149
|
-
const
|
|
150
|
-
|
|
151
|
-
const paragraphContent =
|
|
201
|
+
const promptText = plan.promptText ?? translateQti('prompt.choice.selectOne', { target: view.dom });
|
|
202
|
+
const prompt = promptType.create(null, promptParagraphType.create(null, schema.text(promptText)));
|
|
203
|
+
const choices = plan.choiceContents.map(content => {
|
|
204
|
+
const paragraphContent = content ?? schema.text(translateQti('choice.option', { target: view.dom }));
|
|
152
205
|
return choiceType.create({ identifier: `SIMPLE_CHOICE_${crypto.randomUUID()}` }, choiceParagraphType.create(null, paragraphContent));
|
|
153
206
|
});
|
|
154
207
|
const interaction = interactionType.create({ responseIdentifier: `RESPONSE_${crypto.randomUUID()}`, maxChoices: 1 }, [prompt, ...choices]);
|
|
155
|
-
const firstBlock =
|
|
156
|
-
const
|
|
157
|
-
|
|
208
|
+
const firstBlock = plan.blocksToReplace[0];
|
|
209
|
+
const lastBlock = plan.blocksToReplace[plan.blocksToReplace.length - 1];
|
|
210
|
+
const $from = state.doc.resolve(firstBlock.pos);
|
|
211
|
+
const $to = state.doc.resolve(lastBlock.end);
|
|
212
|
+
if ($from.parent !== $to.parent || !$from.parent.canReplaceWith($from.index(), $to.index(), interactionType)) {
|
|
158
213
|
return false;
|
|
159
214
|
}
|
|
160
215
|
const tr = state.tr;
|
|
161
|
-
for (let i =
|
|
162
|
-
const block =
|
|
216
|
+
for (let i = plan.blocksToReplace.length - 1; i >= 0; i -= 1) {
|
|
217
|
+
const block = plan.blocksToReplace[i];
|
|
163
218
|
tr.delete(block.pos, block.end);
|
|
164
219
|
}
|
|
165
220
|
tr.insert(firstBlock.pos, interaction);
|
package/dist/components/qti-choice-interaction/commands/insert-choice-interaction.commands.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"insert-choice-interaction.commands.d.ts","sourceRoot":"","sources":["../../../../src/components/qti-choice-interaction/commands/insert-choice-interaction.commands.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"insert-choice-interaction.commands.d.ts","sourceRoot":"","sources":["../../../../src/components/qti-choice-interaction/commands/insert-choice-interaction.commands.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAGjD;;GAEG;AACH,eAAO,MAAM,uBAAuB,EAAE,OAwCrC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,yBAAyB,EAAE,OAcvC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,EAAE,OAA8D,CAAC"}
|
package/dist/components/qti-choice-interaction/commands/insert-choice-interaction.commands.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { chainCommands, splitBlock } from 'prosemirror-commands';
|
|
2
2
|
import { createInsertSiblingOnEnterCommand } from '@qti-editor/interaction-shared/commands/enter.js';
|
|
3
3
|
import { createInsertBlockInteractionCommand } from '@qti-editor/interaction-shared/commands/insert.js';
|
|
4
|
+
import { translateQti } from '@qti-editor/interaction-shared';
|
|
4
5
|
/**
|
|
5
6
|
* Command to insert a choice interaction at the current selection
|
|
6
7
|
*/
|
|
7
|
-
export const insertChoiceInteraction = (state, dispatch) => {
|
|
8
|
+
export const insertChoiceInteraction = (state, dispatch, view) => {
|
|
9
|
+
const target = view?.dom ?? null;
|
|
8
10
|
return createInsertBlockInteractionCommand({
|
|
9
11
|
createNode: currentState => {
|
|
10
12
|
const { schema } = currentState;
|
|
@@ -17,11 +19,11 @@ export const insertChoiceInteraction = (state, dispatch) => {
|
|
|
17
19
|
return null;
|
|
18
20
|
}
|
|
19
21
|
const responseIdentifier = `RESPONSE_${crypto.randomUUID()}`;
|
|
20
|
-
const prompt = promptType.create(null, promptParagraphType.create(null, schema.text('
|
|
22
|
+
const prompt = promptType.create(null, promptParagraphType.create(null, schema.text(translateQti('prompt.choice.default', { target }))));
|
|
21
23
|
const choices = [
|
|
22
|
-
choiceType.create({ identifier: `SIMPLE_CHOICE_${crypto.randomUUID()}` }, choiceParagraphType.create(null, schema.text('
|
|
23
|
-
choiceType.create({ identifier: `SIMPLE_CHOICE_${crypto.randomUUID()}` }, choiceParagraphType.create(null, schema.text('
|
|
24
|
-
choiceType.create({ identifier: `SIMPLE_CHOICE_${crypto.randomUUID()}` }, choiceParagraphType.create(null, schema.text('
|
|
24
|
+
choiceType.create({ identifier: `SIMPLE_CHOICE_${crypto.randomUUID()}` }, choiceParagraphType.create(null, schema.text(translateQti('choice.optionA', { target })))),
|
|
25
|
+
choiceType.create({ identifier: `SIMPLE_CHOICE_${crypto.randomUUID()}` }, choiceParagraphType.create(null, schema.text(translateQti('choice.optionB', { target })))),
|
|
26
|
+
choiceType.create({ identifier: `SIMPLE_CHOICE_${crypto.randomUUID()}` }, choiceParagraphType.create(null, schema.text(translateQti('choice.optionC', { target }))))
|
|
25
27
|
];
|
|
26
28
|
return interactionType.create({ responseIdentifier, maxChoices: 1 }, [prompt, ...choices]);
|
|
27
29
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qti-choice-interaction.d.ts","sourceRoot":"","sources":["../../../src/components/qti-choice-interaction/qti-choice-interaction.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,0DAA0D,CAAC;AAKvF,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG,UAAU,GAAG,SAAS,CAAC;AAChE,QAAA,MAAM,qBAAqB,EAAwD,OAAO,WAAW,CAAC;AAEtG,qBAAa,wBAAyB,SAAQ,qBAAqB;;IACjE,WAAoB,MAAM,8BASzB;
|
|
1
|
+
{"version":3,"file":"qti-choice-interaction.d.ts","sourceRoot":"","sources":["../../../src/components/qti-choice-interaction/qti-choice-interaction.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,0DAA0D,CAAC;AAKvF,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG,UAAU,GAAG,SAAS,CAAC;AAChE,QAAA,MAAM,qBAAqB,EAAwD,OAAO,WAAW,CAAC;AAEtG,qBAAa,wBAAyB,SAAQ,qBAAqB;;IACjE,WAAoB,MAAM,8BASzB;IAGD,UAAU,SAAK;IAGf,UAAU,SAAK;IAGf,OAAO,EAAE,0BAA0B,GAAG,4BAA4B,GAAG,SAAS,CAAC;IAE/E,SAAS,CAAC,UAAU,EAAE,gBAAgB,CAAC;;IAQvC,iBAAiB,IAAI,IAAI;IAOzB,oBAAoB,IAAI,IAAI;IAMnB,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC;IAmC/C,MAAM;CAGhB"}
|
|
@@ -15,7 +15,7 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
|
|
|
15
15
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
16
16
|
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
17
17
|
};
|
|
18
|
-
var _QtiChoiceInteractionEdit_instances, _QtiChoiceInteractionEdit_mutationObserver, _QtiChoiceInteractionEdit_updateChoices;
|
|
18
|
+
var _QtiChoiceInteractionEdit_instances, _QtiChoiceInteractionEdit_mutationObserver, _QtiChoiceInteractionEdit_syncSelectedChoices, _QtiChoiceInteractionEdit_updateChoices;
|
|
19
19
|
import { css, html } from 'lit';
|
|
20
20
|
import { property } from 'lit/decorators.js';
|
|
21
21
|
import { Interaction } from '@qti-editor/interaction-shared/components/interaction.js';
|
|
@@ -57,12 +57,24 @@ export class QtiChoiceInteractionEdit extends ChoiceInteractionBase {
|
|
|
57
57
|
if (changedProperties.has('maxChoices')) {
|
|
58
58
|
__classPrivateFieldGet(this, _QtiChoiceInteractionEdit_instances, "m", _QtiChoiceInteractionEdit_updateChoices).call(this);
|
|
59
59
|
}
|
|
60
|
+
if (changedProperties.has('correctResponse')) {
|
|
61
|
+
__classPrivateFieldGet(this, _QtiChoiceInteractionEdit_instances, "m", _QtiChoiceInteractionEdit_syncSelectedChoices).call(this);
|
|
62
|
+
}
|
|
60
63
|
}
|
|
61
64
|
render() {
|
|
62
65
|
return html `<slot part="prompt" name="prompt"></slot><slot part="slot"></slot>`;
|
|
63
66
|
}
|
|
64
67
|
}
|
|
65
|
-
_QtiChoiceInteractionEdit_mutationObserver = new WeakMap(), _QtiChoiceInteractionEdit_instances = new WeakSet(),
|
|
68
|
+
_QtiChoiceInteractionEdit_mutationObserver = new WeakMap(), _QtiChoiceInteractionEdit_instances = new WeakSet(), _QtiChoiceInteractionEdit_syncSelectedChoices = function _QtiChoiceInteractionEdit_syncSelectedChoices() {
|
|
69
|
+
const identifiers = new Set(typeof this.correctResponse === 'string' && this.correctResponse
|
|
70
|
+
? this.correctResponse.split(',')
|
|
71
|
+
: Array.isArray(this.correctResponse)
|
|
72
|
+
? this.correctResponse
|
|
73
|
+
: []);
|
|
74
|
+
this.querySelectorAll('qti-simple-choice').forEach(choice => {
|
|
75
|
+
choice.setSelected?.(identifiers.has(choice.identifier ?? ''));
|
|
76
|
+
});
|
|
77
|
+
}, _QtiChoiceInteractionEdit_updateChoices = function _QtiChoiceInteractionEdit_updateChoices() {
|
|
66
78
|
this._internals.role = this.maxChoices === 1 ? 'radiogroup' : null;
|
|
67
79
|
const role = this.maxChoices === 1 ? 'radio' : 'checkbox';
|
|
68
80
|
this.querySelectorAll('qti-simple-choice').forEach((choice) => {
|
package/package.json
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qti-editor/interaction-choice",
|
|
3
3
|
"description": "QTI choice interaction schemas, components, commands, and composer",
|
|
4
|
-
"version": "0.1
|
|
4
|
+
"version": "0.2.1",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/Citolab/qti-editor",
|
|
8
|
+
"directory": "packages/prosemirror/interaction-choice"
|
|
9
|
+
},
|
|
5
10
|
"type": "module",
|
|
6
11
|
"main": "./dist/index.js",
|
|
7
12
|
"types": "./dist/index.d.ts",
|
|
@@ -16,19 +21,19 @@
|
|
|
16
21
|
}
|
|
17
22
|
},
|
|
18
23
|
"dependencies": {
|
|
19
|
-
"@qti-components/base": "^1.4.
|
|
20
|
-
"@qti-components/choice-interaction": "^1.1.
|
|
24
|
+
"@qti-components/base": "^1.4.2",
|
|
25
|
+
"@qti-components/choice-interaction": "^1.1.3",
|
|
21
26
|
"@qti-components/interactions": "^1.10.1",
|
|
22
|
-
"@qti-components/interactions-core": "^1.1.
|
|
23
|
-
"@qti-components/utilities": "^1.3.
|
|
24
|
-
"@qti-editor/
|
|
25
|
-
"@qti-editor/
|
|
27
|
+
"@qti-components/interactions-core": "^1.1.3",
|
|
28
|
+
"@qti-components/utilities": "^1.3.2",
|
|
29
|
+
"@qti-editor/interaction-shared": "0.2.1",
|
|
30
|
+
"@qti-editor/interfaces": "0.3.0"
|
|
26
31
|
},
|
|
27
32
|
"peerDependencies": {
|
|
28
33
|
"lit": "^3.3.1"
|
|
29
34
|
},
|
|
30
35
|
"devDependencies": {
|
|
31
|
-
"lit": "^3.3.
|
|
36
|
+
"lit": "^3.3.2",
|
|
32
37
|
"prosemirror-commands": "^1.7.1",
|
|
33
38
|
"prosemirror-model": "^1.25.4",
|
|
34
39
|
"prosemirror-state": "^1.4.4"
|