React Usage¶
Basic Usage¶
import { QuizEditor } from '@grokify/h5p-editor';
import '@grokify/h5p-editor/styles.css';
function App() {
return <QuizEditor />;
}
With Save Handler¶
import { QuizEditor, H5PQuiz } from '@grokify/h5p-editor';
import '@grokify/h5p-editor/styles.css';
function App() {
const handleSave = (quiz: H5PQuiz) => {
// Send to your backend
fetch('/api/quizzes', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(quiz),
});
};
return <QuizEditor onSave={handleSave} />;
}
Ref API for Programmatic Control¶
Use a ref to access editor methods:
import { useRef } from 'react';
import { QuizEditor, QuizEditorRef } from '@grokify/h5p-editor';
import '@grokify/h5p-editor/styles.css';
function App() {
const editorRef = useRef<QuizEditorRef>(null);
const handleExport = () => {
const quiz = editorRef.current?.getContent();
if (quiz) {
const blob = new Blob([JSON.stringify(quiz, null, 2)], { type: 'application/json' });
const url = URL.createObjectURL(blob);
// Download logic...
}
};
const handleValidate = () => {
const result = editorRef.current?.validate();
if (result && !result.valid) {
console.log('Errors:', result.errors);
}
};
return (
<div>
<button onClick={handleExport}>Export JSON</button>
<button onClick={handleValidate}>Validate</button>
<QuizEditor ref={editorRef} />
</div>
);
}
Loading Existing Content¶
import { QuizEditor, H5PQuiz } from '@grokify/h5p-editor';
const existingQuiz: H5PQuiz = {
library: 'H5P.QuestionSet 1.20',
metadata: { title: 'My Quiz' },
params: {
progressType: 'dots',
passPercentage: 70,
questions: [
{
library: 'H5P.MultiChoice 1.16',
params: {
question: 'What is 2 + 2?',
answers: [
{ text: '3', correct: false },
{ text: '4', correct: true },
],
behaviour: {},
},
},
],
},
};
function App() {
return <QuizEditor content={existingQuiz} />;
}
Restricting Question Types¶
Limit which question types users can add:
Theming¶
Built-in Themes¶
Custom Themes via CSS¶
Override CSS custom properties:
.h5p-editor-root {
--h5p-color-primary: #0066cc;
--h5p-color-bg: #ffffff;
--h5p-color-text: #1e293b;
--h5p-color-border: #e2e8f0;
--h5p-color-error: #dc2626;
--h5p-color-success: #16a34a;
}
Read-Only Mode¶
Display quiz content without editing:
Change Tracking¶
Track changes in real-time:
function App() {
const editorRef = useRef<QuizEditorRef>(null);
const [hasChanges, setHasChanges] = useState(false);
const handleChange = (quiz: H5PQuiz) => {
setHasChanges(editorRef.current?.isDirty() ?? false);
};
return (
<div>
{hasChanges && <span>Unsaved changes</span>}
<QuizEditor ref={editorRef} onChange={handleChange} />
</div>
);
}
Props Reference¶
| Prop | Type | Default | Description |
|---|---|---|---|
content |
H5PQuiz |
Empty quiz | Initial content to edit |
onChange |
(quiz: H5PQuiz) => void |
- | Called on every change |
onSave |
(quiz: H5PQuiz) => void |
- | Called when save button clicked |
allowedTypes |
('multipleChoice' \| 'trueFalse' \| 'fillInBlanks')[] |
All | Limit question types |
theme |
'light' \| 'dark' |
'light' |
Color theme |
readOnly |
boolean |
false |
Disable editing |
className |
string |
- | Additional CSS class |
Ref Methods¶
| Method | Returns | Description |
|---|---|---|
getContent() |
H5PQuiz |
Get current quiz content |
setContent(quiz) |
void |
Replace quiz content |
validate() |
ValidationResult |
Validate and return errors |
isDirty() |
boolean |
Check for unsaved changes |