@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 ADDED
@@ -0,0 +1,170 @@
1
+ # @alpha/qti-renderer
2
+
3
+ A QTI 3.0 Assessment Renderer for React applications. Parse, validate, and render QTI XML with customizable themes.
4
+
5
+ ## Features
6
+
7
+ - 📝 **QTI 3.0 Support** - Parse and render QTI 3.0 assessment items
8
+ - 🎨 **Themeable** - Built-in Duolingo and Neobrutalist themes, or create your own
9
+ - 🔒 **Secure** - Server-side parsing and validation keeps correct answers hidden
10
+ - ⚛️ **React 18/19** - Works with latest React and Next.js
11
+ - 📦 **Tree-shakeable** - Only import what you need
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ npm install @alpha/qti-renderer
17
+ # or
18
+ bun add @alpha/qti-renderer
19
+ ```
20
+
21
+ ## Quick Start
22
+
23
+ ### 1. Parse QTI XML (Server-side)
24
+
25
+ ```tsx
26
+ // app/quiz/[id]/page.tsx (Server Component)
27
+ import { parseAssessmentItemXml, validateResponse } from "@alpha/qti-renderer/server"
28
+ import { QTIRenderer } from "@alpha/qti-renderer"
29
+ import "@alpha/qti-renderer/themes/duolingo.css"
30
+
31
+ export default async function QuizPage({ params }) {
32
+ // Fetch and parse QTI XML on the server
33
+ const xml = await fetchQTIFromDatabase(params.id)
34
+ const { item } = await parseAssessmentItemXml(xml)
35
+
36
+ // Create server action for validation
37
+ async function checkAnswer(responses: Record<string, string[]>) {
38
+ "use server"
39
+ return validateResponse(item, responses)
40
+ }
41
+
42
+ return <QuizClient item={item} onValidate={checkAnswer} />
43
+ }
44
+ ```
45
+
46
+ ### 2. Render and Handle Interactions (Client-side)
47
+
48
+ ```tsx
49
+ // app/quiz/[id]/client.tsx
50
+ "use client"
51
+
52
+ import { useState } from "react"
53
+ import { QTIRenderer } from "@alpha/qti-renderer"
54
+ import type { AssessmentItem } from "@alpha/qti-renderer"
55
+
56
+ interface Props {
57
+ item: AssessmentItem
58
+ onValidate: (responses: Record<string, string[]>) => Promise<ValidationResult>
59
+ }
60
+
61
+ export function QuizClient({ item, onValidate }: Props) {
62
+ const [responses, setResponses] = useState<Record<string, string[]>>({})
63
+ const [feedback, setFeedback] = useState(null)
64
+ const [showFeedback, setShowFeedback] = useState(false)
65
+
66
+ const handleCheck = async () => {
67
+ const result = await onValidate(responses)
68
+ setFeedback(result)
69
+ setShowFeedback(true)
70
+ }
71
+
72
+ return (
73
+ <div>
74
+ <QTIRenderer
75
+ item={item}
76
+ theme="duolingo"
77
+ responses={responses}
78
+ onResponseChange={(id, values) =>
79
+ setResponses(prev => ({ ...prev, [id]: values }))
80
+ }
81
+ showFeedback={showFeedback}
82
+ feedback={feedback}
83
+ />
84
+
85
+ <button onClick={handleCheck}>Check Answer</button>
86
+ </div>
87
+ )
88
+ }
89
+ ```
90
+
91
+ ## Themes
92
+
93
+ ### Built-in Themes
94
+
95
+ Import the CSS for your chosen theme:
96
+
97
+ ```tsx
98
+ // Duolingo-style (rounded, friendly)
99
+ import "@alpha/qti-renderer/themes/duolingo.css"
100
+
101
+ // Neobrutalist (bold, sharp)
102
+ import "@alpha/qti-renderer/themes/neobrutalist.css"
103
+
104
+ // Base only (minimal styling)
105
+ import "@alpha/qti-renderer/themes/base.css"
106
+ ```
107
+
108
+ Then set the theme prop:
109
+
110
+ ```tsx
111
+ <QTIRenderer theme="duolingo" ... />
112
+ <QTIRenderer theme="neobrutalist" ... />
113
+ ```
114
+
115
+ ### Custom Themes
116
+
117
+ Create your own theme by overriding CSS variables:
118
+
119
+ ```css
120
+ [data-qti-theme="my-theme"] {
121
+ --qti-container-bg: #1a1a2e;
122
+ --qti-container-border: #ffffff;
123
+ --qti-choice-selected-bg: #ff6b6b;
124
+ /* ... see base.css for all variables */
125
+ }
126
+ ```
127
+
128
+ ## API Reference
129
+
130
+ ### `<QTIRenderer />`
131
+
132
+ | Prop | Type | Description |
133
+ |------|------|-------------|
134
+ | `item` | `AssessmentItem` | The parsed QTI assessment item |
135
+ | `theme` | `string` | Theme name (default: "duolingo") |
136
+ | `responses` | `Record<string, string[]>` | Current user responses |
137
+ | `onResponseChange` | `(id, values) => void` | Called when user changes response |
138
+ | `showFeedback` | `boolean` | Whether to show feedback |
139
+ | `feedback` | `ResponseFeedback` | Overall feedback data |
140
+ | `disabled` | `boolean` | Disable all interactions |
141
+
142
+ ### `parseAssessmentItemXml(xml)`
143
+
144
+ Parses QTI XML into an `AssessmentItem`. Server-side only.
145
+
146
+ ```ts
147
+ const { success, item, error } = await parseAssessmentItemXml(xml)
148
+ ```
149
+
150
+ ### `validateResponse(item, responses)`
151
+
152
+ Validates user responses against correct answers. Server-side only.
153
+
154
+ ```ts
155
+ const result = await validateResponse(item, responses)
156
+ // { isCorrect, responses, feedbackHtml, score, maxScore }
157
+ ```
158
+
159
+ ## Supported Interaction Types
160
+
161
+ - ✅ Choice Interaction (single & multiple)
162
+ - ✅ Inline Choice Interaction (dropdowns)
163
+ - ✅ Text Entry Interaction
164
+ - 🚧 Order Interaction
165
+ - 🚧 Gap Match Interaction
166
+ - 🚧 Match Interaction
167
+
168
+ ## License
169
+
170
+ MIT
@@ -0,0 +1,27 @@
1
+ import { D as DisplayItem, F as FormShape, V as ValidateResult } from '../types-MOyn9ktl.js';
2
+
3
+ declare function buildDisplayModelFromXml(qtiXml: string): {
4
+ itemKey: string;
5
+ item: DisplayItem;
6
+ shape: FormShape;
7
+ };
8
+
9
+ /**
10
+ * Parses QTI XML and builds a display model for rendering.
11
+ * This is a server action - call it from the server to keep XML processing secure.
12
+ */
13
+ declare function buildDisplayModel(qtiXml: string): Promise<{
14
+ itemKey: string;
15
+ item: DisplayItem;
16
+ shape: FormShape;
17
+ }>;
18
+
19
+ declare function validateResponsesFromXml(qtiXml: string, responses: Record<string, string | string[]>): ValidateResult;
20
+
21
+ /**
22
+ * Validates user responses against the QTI XML.
23
+ * This is a server action - call it from the server to keep correct answers secure.
24
+ */
25
+ declare function validateResponsesSecure(qtiXml: string, responses: Record<string, string | string[]>): Promise<ValidateResult>;
26
+
27
+ export { DisplayItem, FormShape, ValidateResult, buildDisplayModel, buildDisplayModelFromXml, validateResponsesFromXml, validateResponsesSecure };