@superbuilders/incept-renderer 0.1.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.
- package/README.md +170 -0
- package/dist/actions/index.d.ts +27 -0
- package/dist/actions/index.js +1893 -0
- package/dist/actions/index.js.map +1 -0
- package/dist/components/index.d.ts +113 -0
- package/dist/components/index.js +2495 -0
- package/dist/components/index.js.map +1 -0
- package/dist/index.d.ts +59 -0
- package/dist/index.js +3640 -0
- package/dist/index.js.map +1 -0
- package/dist/schema-DxNEXGoq.d.ts +508 -0
- package/dist/types-MOyn9ktl.d.ts +102 -0
- package/package.json +61 -0
|
@@ -0,0 +1,508 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { D as DisplayItem, a as DisplayBlock } from './types-MOyn9ktl.js';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
|
|
5
|
+
/** Theme options for the QTI renderer */
|
|
6
|
+
type QTITheme = "duolingo" | "neobrutalist" | (string & {});
|
|
7
|
+
/** Feedback result for a single response */
|
|
8
|
+
interface ResponseFeedback {
|
|
9
|
+
isCorrect: boolean;
|
|
10
|
+
messageHtml?: string;
|
|
11
|
+
}
|
|
12
|
+
/** Correctness info for selected choices */
|
|
13
|
+
interface ChoiceCorrectness {
|
|
14
|
+
id: string;
|
|
15
|
+
isCorrect: boolean;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Props for the QTIRenderer component.
|
|
19
|
+
*
|
|
20
|
+
* This is a **controlled, display-only component**. It renders the question
|
|
21
|
+
* and captures user input, but does NOT include submit buttons or flow logic.
|
|
22
|
+
* The consuming app is responsible for:
|
|
23
|
+
* - Providing responses state
|
|
24
|
+
* - Handling submission
|
|
25
|
+
* - Providing feedback after validation
|
|
26
|
+
* - Rendering buttons (Check, Try Again, Continue, etc.)
|
|
27
|
+
*/
|
|
28
|
+
interface QTIRendererProps {
|
|
29
|
+
/**
|
|
30
|
+
* The display-safe item to render.
|
|
31
|
+
* Use `buildDisplayModel()` to create this from a parsed AssessmentItem.
|
|
32
|
+
*/
|
|
33
|
+
item: DisplayItem;
|
|
34
|
+
/**
|
|
35
|
+
* Current user responses, keyed by response identifier.
|
|
36
|
+
* This is a controlled component - you must manage this state.
|
|
37
|
+
* @example { "RESPONSE": "A" } or { "RESPONSE": ["A", "C"] }
|
|
38
|
+
*/
|
|
39
|
+
responses: Record<string, string | string[]>;
|
|
40
|
+
/**
|
|
41
|
+
* Callback fired when user selects/changes an answer.
|
|
42
|
+
* Update your responses state in this callback.
|
|
43
|
+
*/
|
|
44
|
+
onResponseChange: (responseId: string, value: string | string[]) => void;
|
|
45
|
+
/**
|
|
46
|
+
* Theme to apply. Defaults to "duolingo".
|
|
47
|
+
* Available themes: "duolingo", "neobrutalist", or any custom theme
|
|
48
|
+
* defined via `[data-qti-theme="your-theme"]` CSS.
|
|
49
|
+
*/
|
|
50
|
+
theme?: QTITheme;
|
|
51
|
+
/**
|
|
52
|
+
* Whether to show feedback states (correct/incorrect styling).
|
|
53
|
+
* Set to true after validation to display results.
|
|
54
|
+
*/
|
|
55
|
+
showFeedback?: boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Whether to disable all interactions.
|
|
58
|
+
* Typically set to true when showFeedback is true.
|
|
59
|
+
*/
|
|
60
|
+
disabled?: boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Per-choice correctness for highlighting selected answers.
|
|
63
|
+
* Keyed by response identifier.
|
|
64
|
+
*/
|
|
65
|
+
choiceCorrectness?: Record<string, ChoiceCorrectness[]>;
|
|
66
|
+
/**
|
|
67
|
+
* Per-response feedback messages to display.
|
|
68
|
+
* Keyed by response identifier.
|
|
69
|
+
*/
|
|
70
|
+
responseFeedback?: Record<string, ResponseFeedback>;
|
|
71
|
+
/**
|
|
72
|
+
* Overall feedback to display at the end of the question.
|
|
73
|
+
*/
|
|
74
|
+
overallFeedback?: ResponseFeedback;
|
|
75
|
+
/**
|
|
76
|
+
* Additional CSS class for the container.
|
|
77
|
+
*/
|
|
78
|
+
className?: string;
|
|
79
|
+
}
|
|
80
|
+
interface ContentBlockRendererProps {
|
|
81
|
+
/** The content block to render */
|
|
82
|
+
block: DisplayBlock;
|
|
83
|
+
/** Current user responses */
|
|
84
|
+
responses?: Record<string, string | string[]>;
|
|
85
|
+
/** Callback when user selects an answer */
|
|
86
|
+
onAnswerSelect?: (responseIdentifier: string, value: string | string[]) => void;
|
|
87
|
+
/** Whether to show feedback */
|
|
88
|
+
showFeedback?: boolean;
|
|
89
|
+
/** Whether to disable interactions */
|
|
90
|
+
disabled?: boolean;
|
|
91
|
+
/** Selected-only correctness mapping for this render pass */
|
|
92
|
+
selectedChoicesByResponse?: Record<string, Array<{
|
|
93
|
+
id: string;
|
|
94
|
+
isCorrect: boolean;
|
|
95
|
+
}>>;
|
|
96
|
+
/** Optional per-response feedback messages from server */
|
|
97
|
+
perResponseFeedback?: Record<string, {
|
|
98
|
+
isCorrect: boolean;
|
|
99
|
+
messageHtml?: string;
|
|
100
|
+
}>;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Renders a single content block (stimulus or interaction)
|
|
104
|
+
*/
|
|
105
|
+
declare function ContentBlockRenderer({ block, responses, onAnswerSelect, showFeedback, disabled, selectedChoicesByResponse, perResponseFeedback }: ContentBlockRendererProps): react_jsx_runtime.JSX.Element | null;
|
|
106
|
+
/**
|
|
107
|
+
* A controlled, display-only component for rendering QTI assessment items.
|
|
108
|
+
*
|
|
109
|
+
* **This component does NOT include buttons or submission logic.**
|
|
110
|
+
* The consuming app is responsible for:
|
|
111
|
+
* - Managing `responses` state
|
|
112
|
+
* - Rendering Check/Submit/Try Again buttons
|
|
113
|
+
* - Calling validation APIs
|
|
114
|
+
* - Providing feedback data after validation
|
|
115
|
+
*
|
|
116
|
+
* @example
|
|
117
|
+
* ```tsx
|
|
118
|
+
* const [responses, setResponses] = useState({})
|
|
119
|
+
* const [feedback, setFeedback] = useState(null)
|
|
120
|
+
*
|
|
121
|
+
* <QTIRenderer
|
|
122
|
+
* item={displayItem}
|
|
123
|
+
* responses={responses}
|
|
124
|
+
* onResponseChange={(id, value) => setResponses(prev => ({ ...prev, [id]: value }))}
|
|
125
|
+
* theme="neobrutalist"
|
|
126
|
+
* showFeedback={!!feedback}
|
|
127
|
+
* responseFeedback={feedback?.perResponse}
|
|
128
|
+
* overallFeedback={feedback?.overall}
|
|
129
|
+
* disabled={!!feedback}
|
|
130
|
+
* />
|
|
131
|
+
*
|
|
132
|
+
* <button onClick={handleCheck}>Check Answer</button>
|
|
133
|
+
* ```
|
|
134
|
+
*/
|
|
135
|
+
declare function QTIRenderer({ item, responses, onResponseChange, theme, showFeedback, disabled, choiceCorrectness, responseFeedback, overallFeedback, className }: QTIRendererProps): react_jsx_runtime.JSX.Element;
|
|
136
|
+
|
|
137
|
+
declare const ChoiceInteractionSchema: z.ZodObject<{
|
|
138
|
+
responseIdentifier: z.ZodString;
|
|
139
|
+
shuffle: z.ZodBoolean;
|
|
140
|
+
minChoices: z.ZodNumber;
|
|
141
|
+
maxChoices: z.ZodNumber;
|
|
142
|
+
promptHtml: z.ZodString;
|
|
143
|
+
choices: z.ZodArray<z.ZodObject<{
|
|
144
|
+
identifier: z.ZodString;
|
|
145
|
+
contentHtml: z.ZodString;
|
|
146
|
+
inlineFeedbackHtml: z.ZodOptional<z.ZodString>;
|
|
147
|
+
}, z.core.$strip>>;
|
|
148
|
+
type: z.ZodLiteral<"choiceInteraction">;
|
|
149
|
+
}, z.core.$strip>;
|
|
150
|
+
type ChoiceInteraction = z.infer<typeof ChoiceInteractionSchema>;
|
|
151
|
+
declare const AnyInteractionSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
152
|
+
responseIdentifier: z.ZodString;
|
|
153
|
+
shuffle: z.ZodBoolean;
|
|
154
|
+
minChoices: z.ZodNumber;
|
|
155
|
+
maxChoices: z.ZodNumber;
|
|
156
|
+
promptHtml: z.ZodString;
|
|
157
|
+
choices: z.ZodArray<z.ZodObject<{
|
|
158
|
+
identifier: z.ZodString;
|
|
159
|
+
contentHtml: z.ZodString;
|
|
160
|
+
inlineFeedbackHtml: z.ZodOptional<z.ZodString>;
|
|
161
|
+
}, z.core.$strip>>;
|
|
162
|
+
type: z.ZodLiteral<"choiceInteraction">;
|
|
163
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
164
|
+
responseIdentifier: z.ZodString;
|
|
165
|
+
shuffle: z.ZodBoolean;
|
|
166
|
+
choices: z.ZodArray<z.ZodObject<{
|
|
167
|
+
identifier: z.ZodString;
|
|
168
|
+
contentHtml: z.ZodString;
|
|
169
|
+
}, z.core.$strip>>;
|
|
170
|
+
type: z.ZodLiteral<"inlineChoiceInteraction">;
|
|
171
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
172
|
+
responseIdentifier: z.ZodString;
|
|
173
|
+
expectedLength: z.ZodOptional<z.ZodNumber>;
|
|
174
|
+
placeholderText: z.ZodOptional<z.ZodString>;
|
|
175
|
+
patternMask: z.ZodOptional<z.ZodString>;
|
|
176
|
+
type: z.ZodLiteral<"textEntryInteraction">;
|
|
177
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
178
|
+
responseIdentifier: z.ZodString;
|
|
179
|
+
shuffle: z.ZodBoolean;
|
|
180
|
+
minChoices: z.ZodNumber;
|
|
181
|
+
maxChoices: z.ZodOptional<z.ZodNumber>;
|
|
182
|
+
orientation: z.ZodEnum<{
|
|
183
|
+
vertical: "vertical";
|
|
184
|
+
horizontal: "horizontal";
|
|
185
|
+
}>;
|
|
186
|
+
promptHtml: z.ZodString;
|
|
187
|
+
choices: z.ZodArray<z.ZodObject<{
|
|
188
|
+
identifier: z.ZodString;
|
|
189
|
+
contentHtml: z.ZodString;
|
|
190
|
+
inlineFeedbackHtml: z.ZodOptional<z.ZodString>;
|
|
191
|
+
}, z.core.$strip>>;
|
|
192
|
+
type: z.ZodLiteral<"orderInteraction">;
|
|
193
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
194
|
+
responseIdentifier: z.ZodString;
|
|
195
|
+
shuffle: z.ZodBoolean;
|
|
196
|
+
gapTexts: z.ZodArray<z.ZodObject<{
|
|
197
|
+
identifier: z.ZodString;
|
|
198
|
+
contentHtml: z.ZodString;
|
|
199
|
+
matchMax: z.ZodNumber;
|
|
200
|
+
}, z.core.$strip>>;
|
|
201
|
+
gaps: z.ZodArray<z.ZodObject<{
|
|
202
|
+
identifier: z.ZodString;
|
|
203
|
+
}, z.core.$strip>>;
|
|
204
|
+
contentHtml: z.ZodString;
|
|
205
|
+
type: z.ZodLiteral<"gapMatchInteraction">;
|
|
206
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
207
|
+
responseIdentifier: z.ZodString;
|
|
208
|
+
shuffle: z.ZodBoolean;
|
|
209
|
+
maxAssociations: z.ZodNumber;
|
|
210
|
+
sourceChoices: z.ZodArray<z.ZodObject<{
|
|
211
|
+
identifier: z.ZodString;
|
|
212
|
+
matchMax: z.ZodNumber;
|
|
213
|
+
contentHtml: z.ZodString;
|
|
214
|
+
}, z.core.$strip>>;
|
|
215
|
+
targetChoices: z.ZodArray<z.ZodObject<{
|
|
216
|
+
identifier: z.ZodString;
|
|
217
|
+
matchMax: z.ZodNumber;
|
|
218
|
+
contentHtml: z.ZodString;
|
|
219
|
+
}, z.core.$strip>>;
|
|
220
|
+
promptHtml: z.ZodString;
|
|
221
|
+
type: z.ZodLiteral<"matchInteraction">;
|
|
222
|
+
}, z.core.$strip>], "type">;
|
|
223
|
+
type AnyInteraction = z.infer<typeof AnyInteractionSchema>;
|
|
224
|
+
declare const ResponseDeclarationSchema: z.ZodObject<{
|
|
225
|
+
identifier: z.ZodString;
|
|
226
|
+
cardinality: z.ZodEnum<{
|
|
227
|
+
single: "single";
|
|
228
|
+
multiple: "multiple";
|
|
229
|
+
ordered: "ordered";
|
|
230
|
+
}>;
|
|
231
|
+
baseType: z.ZodEnum<{
|
|
232
|
+
string: "string";
|
|
233
|
+
boolean: "boolean";
|
|
234
|
+
directedPair: "directedPair";
|
|
235
|
+
identifier: "identifier";
|
|
236
|
+
float: "float";
|
|
237
|
+
integer: "integer";
|
|
238
|
+
pair: "pair";
|
|
239
|
+
}>;
|
|
240
|
+
correctResponse: z.ZodObject<{
|
|
241
|
+
values: z.ZodArray<z.ZodString>;
|
|
242
|
+
}, z.core.$strip>;
|
|
243
|
+
mapping: z.ZodOptional<z.ZodObject<{
|
|
244
|
+
defaultValue: z.ZodDefault<z.ZodNumber>;
|
|
245
|
+
lowerBound: z.ZodOptional<z.ZodNumber>;
|
|
246
|
+
upperBound: z.ZodOptional<z.ZodNumber>;
|
|
247
|
+
entries: z.ZodArray<z.ZodObject<{
|
|
248
|
+
key: z.ZodString;
|
|
249
|
+
value: z.ZodNumber;
|
|
250
|
+
}, z.core.$strip>>;
|
|
251
|
+
}, z.core.$strip>>;
|
|
252
|
+
}, z.core.$strip>;
|
|
253
|
+
type ResponseDeclaration = z.infer<typeof ResponseDeclarationSchema>;
|
|
254
|
+
declare const FeedbackBlockSchema: z.ZodObject<{
|
|
255
|
+
outcomeIdentifier: z.ZodString;
|
|
256
|
+
identifier: z.ZodString;
|
|
257
|
+
showHide: z.ZodDefault<z.ZodEnum<{
|
|
258
|
+
show: "show";
|
|
259
|
+
hide: "hide";
|
|
260
|
+
}>>;
|
|
261
|
+
contentHtml: z.ZodString;
|
|
262
|
+
}, z.core.$strip>;
|
|
263
|
+
type FeedbackBlock = z.infer<typeof FeedbackBlockSchema>;
|
|
264
|
+
declare const BaseRuleSchema: z.ZodObject<{
|
|
265
|
+
type: z.ZodLiteral<"setOutcomeValue">;
|
|
266
|
+
identifier: z.ZodString;
|
|
267
|
+
value: z.ZodString;
|
|
268
|
+
}, z.core.$strip>;
|
|
269
|
+
type BaseRule = z.infer<typeof BaseRuleSchema>;
|
|
270
|
+
declare const MatchConditionSchema: z.ZodObject<{
|
|
271
|
+
type: z.ZodLiteral<"match">;
|
|
272
|
+
variable: z.ZodString;
|
|
273
|
+
correct: z.ZodLiteral<true>;
|
|
274
|
+
}, z.core.$strip>;
|
|
275
|
+
type MatchCondition = z.infer<typeof MatchConditionSchema>;
|
|
276
|
+
declare const MatchValueConditionSchema: z.ZodObject<{
|
|
277
|
+
type: z.ZodLiteral<"matchValue">;
|
|
278
|
+
variable: z.ZodString;
|
|
279
|
+
value: z.ZodString;
|
|
280
|
+
}, z.core.$strip>;
|
|
281
|
+
type MatchValueCondition = z.infer<typeof MatchValueConditionSchema>;
|
|
282
|
+
declare const StringMatchConditionSchema: z.ZodObject<{
|
|
283
|
+
type: z.ZodLiteral<"stringMatch">;
|
|
284
|
+
variable: z.ZodString;
|
|
285
|
+
value: z.ZodString;
|
|
286
|
+
caseSensitive: z.ZodBoolean;
|
|
287
|
+
}, z.core.$strip>;
|
|
288
|
+
type StringMatchCondition = z.infer<typeof StringMatchConditionSchema>;
|
|
289
|
+
declare const MemberConditionSchema: z.ZodObject<{
|
|
290
|
+
type: z.ZodLiteral<"member">;
|
|
291
|
+
variable: z.ZodString;
|
|
292
|
+
value: z.ZodString;
|
|
293
|
+
}, z.core.$strip>;
|
|
294
|
+
type MemberCondition = z.infer<typeof MemberConditionSchema>;
|
|
295
|
+
declare const EqualMapResponseConditionSchema: z.ZodObject<{
|
|
296
|
+
type: z.ZodLiteral<"equalMapResponse">;
|
|
297
|
+
variable: z.ZodString;
|
|
298
|
+
value: z.ZodString;
|
|
299
|
+
}, z.core.$strip>;
|
|
300
|
+
type EqualMapResponseCondition = z.infer<typeof EqualMapResponseConditionSchema>;
|
|
301
|
+
type AndCondition = {
|
|
302
|
+
type: "and";
|
|
303
|
+
conditions: AnyCondition[];
|
|
304
|
+
};
|
|
305
|
+
type OrCondition = {
|
|
306
|
+
type: "or";
|
|
307
|
+
conditions: AnyCondition[];
|
|
308
|
+
};
|
|
309
|
+
type NotCondition = {
|
|
310
|
+
type: "not";
|
|
311
|
+
condition: AnyCondition;
|
|
312
|
+
};
|
|
313
|
+
type AnyCondition = MatchCondition | MatchValueCondition | StringMatchCondition | MemberCondition | AndCondition | OrCondition | NotCondition | EqualMapResponseCondition;
|
|
314
|
+
type ConditionBranch = {
|
|
315
|
+
condition?: AnyCondition;
|
|
316
|
+
actions: BaseRule[];
|
|
317
|
+
nestedRules?: ResponseRule[];
|
|
318
|
+
};
|
|
319
|
+
type ResponseRule = {
|
|
320
|
+
type: "condition";
|
|
321
|
+
branches: ConditionBranch[];
|
|
322
|
+
} | {
|
|
323
|
+
type: "action";
|
|
324
|
+
action: BaseRule;
|
|
325
|
+
};
|
|
326
|
+
declare const ResponseProcessingSchema: z.ZodObject<{
|
|
327
|
+
rules: z.ZodArray<z.ZodType<ResponseRule, unknown, z.core.$ZodTypeInternals<ResponseRule, unknown>>>;
|
|
328
|
+
scoring: z.ZodObject<{
|
|
329
|
+
responseIdentifier: z.ZodString;
|
|
330
|
+
correctScore: z.ZodNumber;
|
|
331
|
+
incorrectScore: z.ZodNumber;
|
|
332
|
+
}, z.core.$strip>;
|
|
333
|
+
}, z.core.$strip>;
|
|
334
|
+
type ResponseProcessing = z.infer<typeof ResponseProcessingSchema>;
|
|
335
|
+
declare const AssessmentItemSchema: z.ZodObject<{
|
|
336
|
+
identifier: z.ZodString;
|
|
337
|
+
title: z.ZodString;
|
|
338
|
+
timeDependent: z.ZodBoolean;
|
|
339
|
+
xmlLang: z.ZodString;
|
|
340
|
+
responseDeclarations: z.ZodArray<z.ZodObject<{
|
|
341
|
+
identifier: z.ZodString;
|
|
342
|
+
cardinality: z.ZodEnum<{
|
|
343
|
+
single: "single";
|
|
344
|
+
multiple: "multiple";
|
|
345
|
+
ordered: "ordered";
|
|
346
|
+
}>;
|
|
347
|
+
baseType: z.ZodEnum<{
|
|
348
|
+
string: "string";
|
|
349
|
+
boolean: "boolean";
|
|
350
|
+
directedPair: "directedPair";
|
|
351
|
+
identifier: "identifier";
|
|
352
|
+
float: "float";
|
|
353
|
+
integer: "integer";
|
|
354
|
+
pair: "pair";
|
|
355
|
+
}>;
|
|
356
|
+
correctResponse: z.ZodObject<{
|
|
357
|
+
values: z.ZodArray<z.ZodString>;
|
|
358
|
+
}, z.core.$strip>;
|
|
359
|
+
mapping: z.ZodOptional<z.ZodObject<{
|
|
360
|
+
defaultValue: z.ZodDefault<z.ZodNumber>;
|
|
361
|
+
lowerBound: z.ZodOptional<z.ZodNumber>;
|
|
362
|
+
upperBound: z.ZodOptional<z.ZodNumber>;
|
|
363
|
+
entries: z.ZodArray<z.ZodObject<{
|
|
364
|
+
key: z.ZodString;
|
|
365
|
+
value: z.ZodNumber;
|
|
366
|
+
}, z.core.$strip>>;
|
|
367
|
+
}, z.core.$strip>>;
|
|
368
|
+
}, z.core.$strip>>;
|
|
369
|
+
outcomeDeclarations: z.ZodArray<z.ZodObject<{
|
|
370
|
+
identifier: z.ZodString;
|
|
371
|
+
cardinality: z.ZodEnum<{
|
|
372
|
+
single: "single";
|
|
373
|
+
multiple: "multiple";
|
|
374
|
+
ordered: "ordered";
|
|
375
|
+
}>;
|
|
376
|
+
baseType: z.ZodEnum<{
|
|
377
|
+
string: "string";
|
|
378
|
+
boolean: "boolean";
|
|
379
|
+
directedPair: "directedPair";
|
|
380
|
+
identifier: "identifier";
|
|
381
|
+
float: "float";
|
|
382
|
+
integer: "integer";
|
|
383
|
+
pair: "pair";
|
|
384
|
+
}>;
|
|
385
|
+
defaultValue: z.ZodOptional<z.ZodObject<{
|
|
386
|
+
value: z.ZodString;
|
|
387
|
+
}, z.core.$strip>>;
|
|
388
|
+
}, z.core.$strip>>;
|
|
389
|
+
itemBody: z.ZodObject<{
|
|
390
|
+
contentBlocks: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
391
|
+
type: z.ZodLiteral<"stimulus">;
|
|
392
|
+
html: z.ZodString;
|
|
393
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
394
|
+
type: z.ZodLiteral<"richStimulus">;
|
|
395
|
+
html: z.ZodString;
|
|
396
|
+
inlineEmbeds: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
397
|
+
responseIdentifier: z.ZodString;
|
|
398
|
+
shuffle: z.ZodBoolean;
|
|
399
|
+
choices: z.ZodArray<z.ZodObject<{
|
|
400
|
+
identifier: z.ZodString;
|
|
401
|
+
contentHtml: z.ZodString;
|
|
402
|
+
}, z.core.$strip>>;
|
|
403
|
+
type: z.ZodLiteral<"inlineChoiceInteraction">;
|
|
404
|
+
}, z.core.$strip>>;
|
|
405
|
+
textEmbeds: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
406
|
+
responseIdentifier: z.ZodString;
|
|
407
|
+
expectedLength: z.ZodOptional<z.ZodNumber>;
|
|
408
|
+
placeholderText: z.ZodOptional<z.ZodString>;
|
|
409
|
+
patternMask: z.ZodOptional<z.ZodString>;
|
|
410
|
+
type: z.ZodLiteral<"textEntryInteraction">;
|
|
411
|
+
}, z.core.$strip>>;
|
|
412
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
413
|
+
type: z.ZodLiteral<"interaction">;
|
|
414
|
+
interaction: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
415
|
+
responseIdentifier: z.ZodString;
|
|
416
|
+
shuffle: z.ZodBoolean;
|
|
417
|
+
minChoices: z.ZodNumber;
|
|
418
|
+
maxChoices: z.ZodNumber;
|
|
419
|
+
promptHtml: z.ZodString;
|
|
420
|
+
choices: z.ZodArray<z.ZodObject<{
|
|
421
|
+
identifier: z.ZodString;
|
|
422
|
+
contentHtml: z.ZodString;
|
|
423
|
+
inlineFeedbackHtml: z.ZodOptional<z.ZodString>;
|
|
424
|
+
}, z.core.$strip>>;
|
|
425
|
+
type: z.ZodLiteral<"choiceInteraction">;
|
|
426
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
427
|
+
responseIdentifier: z.ZodString;
|
|
428
|
+
shuffle: z.ZodBoolean;
|
|
429
|
+
choices: z.ZodArray<z.ZodObject<{
|
|
430
|
+
identifier: z.ZodString;
|
|
431
|
+
contentHtml: z.ZodString;
|
|
432
|
+
}, z.core.$strip>>;
|
|
433
|
+
type: z.ZodLiteral<"inlineChoiceInteraction">;
|
|
434
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
435
|
+
responseIdentifier: z.ZodString;
|
|
436
|
+
expectedLength: z.ZodOptional<z.ZodNumber>;
|
|
437
|
+
placeholderText: z.ZodOptional<z.ZodString>;
|
|
438
|
+
patternMask: z.ZodOptional<z.ZodString>;
|
|
439
|
+
type: z.ZodLiteral<"textEntryInteraction">;
|
|
440
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
441
|
+
responseIdentifier: z.ZodString;
|
|
442
|
+
shuffle: z.ZodBoolean;
|
|
443
|
+
minChoices: z.ZodNumber;
|
|
444
|
+
maxChoices: z.ZodOptional<z.ZodNumber>;
|
|
445
|
+
orientation: z.ZodEnum<{
|
|
446
|
+
vertical: "vertical";
|
|
447
|
+
horizontal: "horizontal";
|
|
448
|
+
}>;
|
|
449
|
+
promptHtml: z.ZodString;
|
|
450
|
+
choices: z.ZodArray<z.ZodObject<{
|
|
451
|
+
identifier: z.ZodString;
|
|
452
|
+
contentHtml: z.ZodString;
|
|
453
|
+
inlineFeedbackHtml: z.ZodOptional<z.ZodString>;
|
|
454
|
+
}, z.core.$strip>>;
|
|
455
|
+
type: z.ZodLiteral<"orderInteraction">;
|
|
456
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
457
|
+
responseIdentifier: z.ZodString;
|
|
458
|
+
shuffle: z.ZodBoolean;
|
|
459
|
+
gapTexts: z.ZodArray<z.ZodObject<{
|
|
460
|
+
identifier: z.ZodString;
|
|
461
|
+
contentHtml: z.ZodString;
|
|
462
|
+
matchMax: z.ZodNumber;
|
|
463
|
+
}, z.core.$strip>>;
|
|
464
|
+
gaps: z.ZodArray<z.ZodObject<{
|
|
465
|
+
identifier: z.ZodString;
|
|
466
|
+
}, z.core.$strip>>;
|
|
467
|
+
contentHtml: z.ZodString;
|
|
468
|
+
type: z.ZodLiteral<"gapMatchInteraction">;
|
|
469
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
470
|
+
responseIdentifier: z.ZodString;
|
|
471
|
+
shuffle: z.ZodBoolean;
|
|
472
|
+
maxAssociations: z.ZodNumber;
|
|
473
|
+
sourceChoices: z.ZodArray<z.ZodObject<{
|
|
474
|
+
identifier: z.ZodString;
|
|
475
|
+
matchMax: z.ZodNumber;
|
|
476
|
+
contentHtml: z.ZodString;
|
|
477
|
+
}, z.core.$strip>>;
|
|
478
|
+
targetChoices: z.ZodArray<z.ZodObject<{
|
|
479
|
+
identifier: z.ZodString;
|
|
480
|
+
matchMax: z.ZodNumber;
|
|
481
|
+
contentHtml: z.ZodString;
|
|
482
|
+
}, z.core.$strip>>;
|
|
483
|
+
promptHtml: z.ZodString;
|
|
484
|
+
type: z.ZodLiteral<"matchInteraction">;
|
|
485
|
+
}, z.core.$strip>], "type">;
|
|
486
|
+
}, z.core.$strip>]>>;
|
|
487
|
+
feedbackBlocks: z.ZodArray<z.ZodObject<{
|
|
488
|
+
outcomeIdentifier: z.ZodString;
|
|
489
|
+
identifier: z.ZodString;
|
|
490
|
+
showHide: z.ZodDefault<z.ZodEnum<{
|
|
491
|
+
show: "show";
|
|
492
|
+
hide: "hide";
|
|
493
|
+
}>>;
|
|
494
|
+
contentHtml: z.ZodString;
|
|
495
|
+
}, z.core.$strip>>;
|
|
496
|
+
}, z.core.$strip>;
|
|
497
|
+
responseProcessing: z.ZodObject<{
|
|
498
|
+
rules: z.ZodArray<z.ZodType<ResponseRule, unknown, z.core.$ZodTypeInternals<ResponseRule, unknown>>>;
|
|
499
|
+
scoring: z.ZodObject<{
|
|
500
|
+
responseIdentifier: z.ZodString;
|
|
501
|
+
correctScore: z.ZodNumber;
|
|
502
|
+
incorrectScore: z.ZodNumber;
|
|
503
|
+
}, z.core.$strip>;
|
|
504
|
+
}, z.core.$strip>;
|
|
505
|
+
}, z.core.$strip>;
|
|
506
|
+
type AssessmentItem = z.infer<typeof AssessmentItemSchema>;
|
|
507
|
+
|
|
508
|
+
export { type AssessmentItem as A, ContentBlockRenderer as C, type FeedbackBlock as F, QTIRenderer as Q, type ResponseFeedback as R, type QTIRendererProps as a, type QTITheme as b, type ChoiceCorrectness as c, type ContentBlockRendererProps as d, type ChoiceInteraction as e, type AnyInteraction as f, type ResponseDeclaration as g, type ResponseProcessing as h, AssessmentItemSchema as i };
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
type DisplayChoice = {
|
|
2
|
+
id: string;
|
|
3
|
+
contentHtml: string;
|
|
4
|
+
inlineFeedbackHtml?: string;
|
|
5
|
+
};
|
|
6
|
+
type DisplayChoiceInteraction = {
|
|
7
|
+
type: "choice";
|
|
8
|
+
responseId: string;
|
|
9
|
+
cardinality: "single" | "multiple";
|
|
10
|
+
promptHtml: string;
|
|
11
|
+
choices: DisplayChoice[];
|
|
12
|
+
minChoices: number;
|
|
13
|
+
maxChoices: number;
|
|
14
|
+
};
|
|
15
|
+
type DisplayTextInteraction = {
|
|
16
|
+
type: "text";
|
|
17
|
+
responseId: string;
|
|
18
|
+
expectedLength?: number;
|
|
19
|
+
placeholder?: string;
|
|
20
|
+
patternMask?: string;
|
|
21
|
+
};
|
|
22
|
+
type DisplayTextEmbed = {
|
|
23
|
+
responseId: string;
|
|
24
|
+
expectedLength?: number;
|
|
25
|
+
placeholder?: string;
|
|
26
|
+
patternMask?: string;
|
|
27
|
+
};
|
|
28
|
+
type DisplayOrderInteraction = {
|
|
29
|
+
type: "order";
|
|
30
|
+
responseId: string;
|
|
31
|
+
promptHtml: string;
|
|
32
|
+
choices: DisplayChoice[];
|
|
33
|
+
orientation: "vertical" | "horizontal";
|
|
34
|
+
};
|
|
35
|
+
type DisplayGapText = {
|
|
36
|
+
id: string;
|
|
37
|
+
contentHtml: string;
|
|
38
|
+
matchMax: number;
|
|
39
|
+
};
|
|
40
|
+
type DisplayGap = {
|
|
41
|
+
id: string;
|
|
42
|
+
};
|
|
43
|
+
type DisplayGapMatchInteraction = {
|
|
44
|
+
type: "gapMatch";
|
|
45
|
+
responseId: string;
|
|
46
|
+
gapTexts: DisplayGapText[];
|
|
47
|
+
gaps: DisplayGap[];
|
|
48
|
+
contentHtml: string;
|
|
49
|
+
};
|
|
50
|
+
type DisplayAssociableChoice = {
|
|
51
|
+
id: string;
|
|
52
|
+
contentHtml: string;
|
|
53
|
+
matchMax: number;
|
|
54
|
+
};
|
|
55
|
+
type DisplayMatchInteraction = {
|
|
56
|
+
type: "match";
|
|
57
|
+
responseId: string;
|
|
58
|
+
promptHtml: string;
|
|
59
|
+
maxAssociations: number;
|
|
60
|
+
sourceChoices: DisplayAssociableChoice[];
|
|
61
|
+
targetChoices: DisplayAssociableChoice[];
|
|
62
|
+
};
|
|
63
|
+
type DisplayInteraction = DisplayChoiceInteraction | DisplayTextInteraction | DisplayOrderInteraction | DisplayGapMatchInteraction | DisplayMatchInteraction;
|
|
64
|
+
type DisplayInlineEmbed = {
|
|
65
|
+
responseId: string;
|
|
66
|
+
shuffle: boolean;
|
|
67
|
+
choices: Array<Pick<DisplayChoice, "id" | "contentHtml">>;
|
|
68
|
+
};
|
|
69
|
+
type DisplayBlock = {
|
|
70
|
+
type: "stimulus";
|
|
71
|
+
html: string;
|
|
72
|
+
} | {
|
|
73
|
+
type: "richStimulus";
|
|
74
|
+
html: string;
|
|
75
|
+
inlineEmbeds: Record<string, DisplayInlineEmbed>;
|
|
76
|
+
textEmbeds: Record<string, DisplayTextEmbed>;
|
|
77
|
+
} | {
|
|
78
|
+
type: "interaction";
|
|
79
|
+
interaction: DisplayInteraction;
|
|
80
|
+
};
|
|
81
|
+
type DisplayItem = {
|
|
82
|
+
title: string;
|
|
83
|
+
contentBlocks: DisplayBlock[];
|
|
84
|
+
};
|
|
85
|
+
type FormShape = Record<string, "single" | "multiple" | "ordered" | "directedPair">;
|
|
86
|
+
type ValidateResult = {
|
|
87
|
+
overallCorrect: boolean;
|
|
88
|
+
perResponse: Record<string, {
|
|
89
|
+
isCorrect: boolean;
|
|
90
|
+
messageHtml?: string;
|
|
91
|
+
}>;
|
|
92
|
+
selectedChoicesByResponse: Record<string, Array<{
|
|
93
|
+
id: string;
|
|
94
|
+
isCorrect: boolean;
|
|
95
|
+
}>>;
|
|
96
|
+
overallFeedback?: {
|
|
97
|
+
isCorrect: boolean;
|
|
98
|
+
messageHtml?: string;
|
|
99
|
+
};
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
export type { DisplayItem as D, FormShape as F, ValidateResult as V, DisplayBlock as a, DisplayChoice as b, DisplayChoiceInteraction as c, DisplayInlineEmbed as d, DisplayTextEmbed as e, DisplayGap as f };
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@superbuilders/incept-renderer",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "QTI 3.0 Assessment Renderer - Parse, validate, and render QTI XML with customizable themes",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./actions": {
|
|
15
|
+
"types": "./dist/actions/index.d.ts",
|
|
16
|
+
"import": "./dist/actions/index.js"
|
|
17
|
+
},
|
|
18
|
+
"./components": {
|
|
19
|
+
"types": "./dist/components/index.d.ts",
|
|
20
|
+
"import": "./dist/components/index.js"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"files": ["dist", "README.md"],
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "tsup",
|
|
26
|
+
"dev": "tsup --watch",
|
|
27
|
+
"typecheck": "tsc --noEmit"
|
|
28
|
+
},
|
|
29
|
+
"peerDependencies": {
|
|
30
|
+
"react": "^18 || ^19",
|
|
31
|
+
"react-dom": "^18 || ^19"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@dnd-kit/core": "^6.3.1",
|
|
35
|
+
"@dnd-kit/sortable": "^10.0.0",
|
|
36
|
+
"@dnd-kit/utilities": "^3.2.2",
|
|
37
|
+
"@radix-ui/react-checkbox": "^1.3.3",
|
|
38
|
+
"@radix-ui/react-label": "^2.1.7",
|
|
39
|
+
"@radix-ui/react-radio-group": "^1.3.8",
|
|
40
|
+
"@radix-ui/react-select": "^2.2.6",
|
|
41
|
+
"@radix-ui/react-separator": "^1.1.7",
|
|
42
|
+
"class-variance-authority": "^0.7.1",
|
|
43
|
+
"clsx": "^2.1.1",
|
|
44
|
+
"fast-xml-parser": "^5.3.0",
|
|
45
|
+
"lucide-react": "^0.548.0",
|
|
46
|
+
"tailwind-merge": "^3.3.1",
|
|
47
|
+
"zod": "^4.1.12"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@types/react": "^19.1.8",
|
|
51
|
+
"@types/react-dom": "^19.1.6",
|
|
52
|
+
"tsup": "^8.0.0",
|
|
53
|
+
"typescript": "^5.8.3"
|
|
54
|
+
},
|
|
55
|
+
"keywords": ["qti", "assessment", "quiz", "testing", "education", "renderer", "react"],
|
|
56
|
+
"license": "MIT",
|
|
57
|
+
"repository": {
|
|
58
|
+
"type": "git",
|
|
59
|
+
"url": "https://github.com/superbuilders/duolingo"
|
|
60
|
+
}
|
|
61
|
+
}
|