QMF Framework

Quizzman Modular Framework v3 — A modular, plugin-based frontend framework for the entire Quizzman ecosystem.

echo '@qmf:registry=https://ui.quizzman.com/registry/' >> .npmrc && pnpm add @qmf/core @qmf/tokens

Features

4-layer Architecture · Plugin system · Error isolation · DevTools

🔌

Plugin System

Register modules as plugins with automatic dependency resolution. Supports eager & lazy loading.

📦

DI Container

Token-based dependency injection — register and resolve services anywhere in your app.

🔒

Error Isolation

Each module has its own error boundary. One module crashing won't affect others.

📊

State Management

Global + isolated module store with Zod schema validation. Selectors, watchers, immutable updates.

🚀

Lazy Loading

Code-split modules, loaded only when needed. CSS auto-injected when plugin mounts.

🛠

DevTools

Event tracing, state inspection, plugin graph — all via window.__QMF_DEVTOOLS__.

📡

Event Bus

Pub/sub with wildcards, scoped bus, and tracing. Inter-module communication without coupling.

🔄

Lifecycle Hooks

Manage module lifecycle: onInit → onMount → onReady → onDestroy. Sync and async.

🌐

HTTP Client

Fetch wrapper with interceptors, retry logic, auth injection, and automatic error mapping.

4-Layer Architecture

Each layer can only import from lower layers — no circular dependencies.

Layer 3 — Modules @qmf/header · @qmf/footer · @qmf/chat-embed · @qmf/noti-embed · @qmf/loading-screen Layer 2 — UI Kit @qmf/ui → Button · Modal · Dropdown · Toast · Panel · Avatar · Badge Layer 1 — Core @qmf/core → EventBus · Store · Lifecycle · Config · HttpClient · DI · PluginLoader · ErrorBoundary Layer 0 — Foundation @qmf/tokens · @qmf/utils → CSS custom properties · Logger · DOM helpers · Fetch wrapper

Quick Start

Choose the integration method that fits your project.

<!-- 1. Load QMF -->
<link rel="stylesheet" href="https://ui.quizzman.com/qmf/dist/tokens.css">
<script src="https://ui.quizzman.com/qmf/dist/qmf.iife.js"></script>

<!-- 2. Init -->
<script>
  QMF.init({
    appId: 'my-app',
    debug: true
  }).then(() => {
    console.log('QMF Ready!');
  });
</script>
// 1. Add to .npmrc (one-time)
// echo '@qmf:registry=https://ui.quizzman.com/registry/' >> .npmrc

// 2. Install
// pnpm add @qmf/core @qmf/tokens @qmf/header

import { QMF, lazy } from '@qmf/core';
import { createHeaderPlugin } from '@qmf/header';
import '@qmf/tokens/css';

// Register plugins
QMF.use(createHeaderPlugin({ brandName: 'My App' }));
QMF.use(lazy(() => import('@qmf/chat-embed')));

// Initialize
await QMF.init({
  appId: 'my-app',
  channel: 'production',
  debug: false
});
import { QMF, lazy, getGlobalEventBus } from '@qmf/core';
import { createHeaderPlugin } from '@qmf/header';
import { createFooterPlugin } from '@qmf/footer';
import '@qmf/tokens/css';

// 1. Register plugins (eager)
QMF.use(createHeaderPlugin({ brandName: 'Quizzman LMS' }));
QMF.use(createFooterPlugin());

// 2. Register plugins (lazy — loaded on demand)
QMF.use(lazy(() => import('@qmf/chat-embed')));
QMF.use(lazy(() => import('@qmf/noti-embed')));

// 3. Init framework
await QMF.init({
  appId: 'quizzman-lms',
  channel: 'production',
  debug: import.meta.env.DEV,
});

// 4. Use event bus
const bus = getGlobalEventBus();
bus.on('auth:login', (user) => console.log('Logged in:', user));
bus.emit('auth:login', { id: 1, name: 'Admin' });

// 5. Access store
const state = QMF.store.getState();
QMF.store.watch(s => s.user, (newUser) => {
  console.log('User changed:', newUser);
});

Core API

Core APIs of @qmf/core

ModuleAPIDescription
EventBus on · off · emit · once Pub/sub with wildcard * and EventBus.scoped(prefix)
Store getState · setState · select · watch Immutable state container, Zod validation, selector + watcher
Lifecycle hook · transition Module lifecycle: onInit → onMount → onReady → onDestroy
Config validateConfig · resolveEnvUrls Zod schema validation + environment URL resolution
HttpClient get · post · put · delete Fetch wrapper: interceptor, retry, auth injection
DI register · resolve · createToken Token-based dependency injection
PluginLoader QMF.use · lazy Plugin registration with dependency graph + lazy loading
ErrorBoundary protect · onError Per-module error isolation, fallback UI

Dynamic Island

Notification pill — System notifications displayed as a "pill" at the top of the page, expands on hover/click.

🎮 Live Demo

Click buttons to see Dynamic Island. Hover to expand, click close button or wait for auto-dismiss.

<!-- 1. Load CSS + JS -->
<link rel="stylesheet"
      href="https://ui.quizzman.com/qmf/dist/modules/header/dynamic-island.css">
<script src="https://ui.quizzman.com/qmf/dist/modules/header/dynamic-island.js"></script>

<!-- 2. Use -->
<script>
  const island = new QMFDynamicIsland();

  // Push a notification
  island.push({
    title:    'System Update',
    message:  'Version 3.0 is now available!',
    icon:     'fas fa-rocket',
    priority: 'info',      // info | success | warning | error | promo
    duration: 6000,        // ms, 0 = sticky
    actions: [
      { label: 'View Details', href: 'https://quizzman.com', primary: true },
      { label: 'Dismiss' }
    ]
  });
</script>
// Constructor
const island = new QMFDynamicIsland({
  autoDismiss: 6000,     // Default auto-dismiss (ms)
  maxQueue:    10,       // Max queued notifications
  hoverExpand: true,     // Expand on hover (desktop)
  container:   document.body
});

// Methods
island.push(data)       // Add notification to queue
island.dismiss()       // Dismiss current, show next
island.expand()        // Expand to full view
island.collapse()      // Collapse to compact pill
island.clear()         // Clear all notifications

// Notification data shape
{
  title:    'string',           // Required — Heading
  message:  'string',           // Required — Body text
  icon:     'fas fa-bell',      // FontAwesome class
  priority: 'info',             // info | success | warning | error | promo
  duration: 6000,               // Auto-dismiss ms (0 = sticky)
  actions:  [                      // Optional buttons
    { label: 'Click', href: '...', primary: true },
    { label: 'Action', onClick: () => {} }
  ]
}
/* Override these CSS variables to customize */
:root {
  --qmf-island-bg:       rgba(15, 15, 30, 0.92);  /* Background */
  --qmf-island-border:   rgba(255, 255, 255, 0.1);
  --qmf-island-text:     #ffffff;
  --qmf-island-text-muted: rgba(255, 255, 255, 0.7);
  --qmf-island-radius:   28px;              /* Compact pill radius */
  --qmf-island-z:        10000;             /* z-index */

  /* Priority colors */
  --qmf-island-info:     #4facfe;
  --qmf-island-success:  #43e97b;
  --qmf-island-warning:  #f5b942;
  --qmf-island-error:    #ff6b6b;
  --qmf-island-promo:    linear-gradient(135deg, #667eea, #764ba2);
}

/* BEM classes */
.qmf-island                     /* Container */
.qmf-island--visible            /* Shown */
.qmf-island--expanded           /* Full view */
.qmf-island--has-queue          /* Queue dots visible */
.qmf-island__compact            /* Pill row */
.qmf-island__icon               /* Icon circle */
.qmf-island__icon--info         /* Priority modifier */
.qmf-island__label              /* Title text */
.qmf-island__body               /* Expanded content */
.qmf-island__actions            /* Action buttons row */
.qmf-island__action--primary    /* Primary CTA */
.qmf-island__queue              /* Queue dots container */
🔔

Queue System

Push multiple notifications in sequence — they're queued and displayed one by one with queue dots indicator.

🎨

5 Priority Levels

info · success · warning · error · promo — each level has its own gradient color.

📱

Responsive + A11y

Responsive on all devices. ARIA role="status", aria-live="polite", prefers-reduced-motion.

🌙

Light / Dark Theme

Auto-detects [data-theme="light"]. All colors via CSS custom properties, easy to override.

💫

Action Buttons

Each notification can have action buttons: link (href) or callback (onClick).

🧰

Zero Dependencies

Just 1 CSS + 1 JS file. No framework or library dependencies. <10KB combined.

📦 CDN Files

CSS https://ui.quizzman.com/qmf/dist/modules/header/dynamic-island.css
JS https://ui.quizzman.com/qmf/dist/modules/header/dynamic-island.js

Documentation

Read detailed documentation for each part of QMF.