@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
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 };
|