@namita_k/react-quml-player
v1.0.23
Published
A comprehensive React-based QUML (Question Markup Language) player for interactive assessments and educational content delivery
Downloads
2,476
Maintainers
Readme
@tekdi/react-quml-player
A comprehensive, high-performance React-based QUML (Question Markup Language) player for interactive assessments and educational content delivery. Built specifically for the React ecosystem with modern patterns, TypeScript support, and extensive customization options.
✨ Features
- 🚀 Native React Integration - Seamless integration with React applications
- 📚 Comprehensive Question Types - MCQ, MMCQ, SA, LA, MTF, ASQ support
- ⏱️ Advanced Timer System - Question-level and assessment-level timers
- 📊 Real-time Telemetry - Built-in analytics and tracking
- 🎨 Fully Customizable - Theming, styling, and component overrides
- 📱 Responsive Design - Mobile-first responsive layouts
- 🔧 TypeScript Support - Full type safety and IntelliSense
- ⚡ Performance Optimized - Tree-shaking, lazy loading, and bundle optimization
- 🎯 Accessibility Ready - WCAG 2.1 AA compliant
- 🔌 Plugin Architecture - Extensible question type system
🚀 Quick Start
Installation
npm install @tekdi/react-quml-playerBasic Usage
import React from "react";
import { QumlPlayer, QumlConfig } from "@tekdi/react-quml-player";
import "@tekdi/react-quml-player/dist/style.css";
const config: QumlConfig = {
apiConfig: {
host: "https://your-api-host.com",
endpoint: "/api/question/v1",
},
telemetryConfig: {
pdata: { id: "your-app", ver: "1.0.0", pid: "assessment" },
env: "production",
channel: "your-channel",
},
};
function MyAssessment() {
return (
<QumlPlayer
questionSetId="your-question-set-id"
config={config}
onComplete={(results) => {
console.log("Assessment completed!", results);
}}
/>
);
}
export default MyAssessment;📖 Documentation
| Document | Description | | ------------------------------------------------ | -------------------------------------------- | | Installation Guide | Complete setup and installation instructions | | Usage Guide | Detailed usage examples and patterns | | API Reference | Complete API documentation | | Examples | Real-world usage examples |
🎯 Supported Question Types
| Type | Description | Features | | -------- | ------------------------------- | --------------------------------------- | | MCQ | Multiple Choice (Single Select) | ✅ Radio buttons, images, hints | | MMCQ | Multiple Choice (Multi Select) | ✅ Checkboxes, partial scoring | | SA | Short Answer | ✅ Text input, file upload, validation | | LA | Long Answer | ✅ Rich text, file upload, word limits | | MTF | Match the Following | ✅ Drag & drop, accessible interactions | | ASQ | Arrange Sequence Question | ✅ Complex logic, detailed feedback |
⚙️ Configuration
Basic Configuration
const config: QumlConfig = {
// API Configuration
apiConfig: {
host: "https://api.example.com",
endpoint: "/api/question/v1",
headers: {
Authorization: "Bearer your-token",
},
},
// Telemetry Configuration
telemetryConfig: {
pdata: { id: "app-id", ver: "1.0.0", pid: "assessment" },
env: "production",
channel: "education",
uid: "user-id",
},
// Player Configuration
questionSetConfig: {
showTimer: true,
showProgress: true,
randomizeQuestions: false,
maxQuestions: 20,
},
};Advanced Configuration
const advancedConfig: QumlConfig = {
config: {
host: process.env.REACT_APP_API_HOST!,
endpoint: "/question/v2",
listApiEndpoint: "/question/v2/list",
timeout: 30000,
retryAttempts: 3,
headers: {
"X-Channel-Id": "your-channel",
"X-App-Id": "your-app",
},
},
context: {
pdata: { id: "your-app", ver: "1.0.0", pid: "assessment" },
channel: "your-channel",
tags: ["your-tags"],
contextRollup: {
l1: "your-l1",
l2: "your-l2",
l3: "your-l3",
l4: "your-l4",
},
objectRollup: {
id: "your-object-id",
ver: "1.0.0",
type: "your-object-type",
},
userData: {
firstName: "your-first-name",
lastName: "your-last-name",
},
uid: "your-user-id",
tenantId: "your-tenant-id",
tenantCode: "your-tenant-code",
host: "https://dev-interface.prathamdigital.org",
endpoint: "/question/v2",
userName: "your-user-name",
accToken: "",
sid: "your-session-id",
did: "your-device-id",
mode: "play",
partner: ["your-partner"],
},
metadata: {}, // QuestionSet
};Section-Level Configuration
The QUML Player supports section-level configuration, including skip policies:
const questionSetWithSections = {
identifier: "multi-section-assessment",
name: "Assessment with Different Policies",
children: [
{
identifier: "practice-section",
name: "Practice Section",
allowSkip: true, // Allow skipping in practice
children: [
/* practice questions */
],
},
{
identifier: "exam-section",
name: "Graded Section",
allowSkip: false, // No skipping allowed
children: [
/* exam questions */
],
},
],
};🎨 Customization
Custom Styling
/* Override default styles */
.my-custom-player {
--quml-primary-color: #your-brand-color;
--quml-background-color: #your-bg-color;
--quml-border-radius: 12px;
}
.my-custom-player .question-container {
padding: 2rem;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}Component Overrides
import { QumlPlayer } from "@tekdi/react-quml-player";
function CustomizedPlayer() {
return (
<QumlPlayer
questionSetId="assessment-123"
config={config}
className="my-custom-player"
// Custom event handlers
onComplete={(results) => {
// Custom completion logic
saveToDatabase(results);
showSuccessMessage();
navigateToResults();
}}
onPlayerStateChange={(state) => {
// Track progress
analytics.track("assessment_progress", {
questionIndex: state.currentQuestionIndex,
score: state.score,
});
}}
/>
);
}🔧 Integration Examples
Next.js
// pages/assessment/[id].tsx
import { QumlPlayer } from "@tekdi/react-quml-player";
import type { GetServerSideProps } from "next";
export default function AssessmentPage({ questionSetId, config }) {
return (
<QumlPlayer
questionSetId={questionSetId}
config={config}
onComplete={(results) => {
// Handle completion
}}
/>
);
}
export const getServerSideProps: GetServerSideProps = async ({ params }) => {
return {
props: {
questionSetId: params?.id,
config: await getAssessmentConfig(),
},
};
};React Router
import { useParams, useNavigate } from "react-router-dom";
import { QumlPlayer } from "@tekdi/react-quml-player";
function AssessmentRoute() {
const { assessmentId } = useParams();
const navigate = useNavigate();
return (
<QumlPlayer
questionSetId={assessmentId!}
config={config}
onComplete={(results) => {
navigate("/results", { state: { results } });
}}
onExit={() => navigate("/dashboard")}
/>
);
}Redux Integration
import { useDispatch, useSelector } from "react-redux";
import { QumlPlayer } from "@tekdi/react-quml-player";
function ConnectedPlayer() {
const dispatch = useDispatch();
const currentUser = useSelector((state) => state.user.current);
return (
<QumlPlayer
questionSetId="assessment-123"
config={{
...config,
telemetryConfig: {
...config.telemetryConfig,
uid: currentUser.id,
},
}}
onComplete={(results) => {
dispatch(saveAssessmentResults(results));
}}
/>
);
}📈 Performance
- Bundle Size: < 300KB gzipped
- Tree Shaking: Full support for optimal bundles
- Lazy Loading: Automatic code splitting for question types
- Memory Efficient: Automatic cleanup and garbage collection
🧪 Testing
# Run type checking
npm run type-check
# Run linting
npm run lint
# Run tests (when implemented)
npm test🤝 Contributing
We welcome contributions! Please see our Contributing Guidelines for details.
Development Setup
# Clone the repository
git clone https://github.com/tekdi/react-quml-spark.git
# Install dependencies
npm install
# Start development server
npm run dev
# Build library
npm run build:lib📦 Publishing
# Build the library
npm run build:lib
# Publish patch version
npm run publish:patch
# Publish minor version
npm run publish:minor
# Publish major version
npm run publish:major
# Publish beta version
npm run publish:beta🗺️ Roadmap
Version 1.1
- [ ] Enhanced question types (Fill-in-the-blank, Hotspot)
- [ ] Offline support with sync capabilities
- [ ] Advanced analytics dashboard
- [ ] React Native compatibility
Version 1.2
- [ ] AI-powered question recommendations
- [ ] Collaborative assessments
- [ ] White-label customization
- [ ] Performance monitoring
Version 2.0
- [ ] Micro-frontend architecture
- [ ] Visual question builder
- [ ] Machine learning integration
- [ ] Enterprise features (SSO, compliance)
📄 License
MIT © TEKDI
🙏 Acknowledgments
- Built on top of the Sunbird ecosystem
- Inspired by the Angular QUML Player
- Community contributions and feedback
📞 Support
- 📚 Documentation
- 🐛 Issues
- 💬 Discussions
- 📧 Contact: [[email protected]]
