npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@zomako/elearning-layout-engine

v1.1.3

Published

A lightweight, responsive, and SCORM-compliant HTML/CSS/JS foundation for eLearning courses

Downloads

219

Readme

eLearning Layout Engine

A lightweight, responsive, and SCORM-compliant HTML/CSS/JS foundation for eLearning courses.

Features

  • Semantic HTML5: Proper HTML elements for accessibility and SEO
  • Responsive Design: Works seamlessly on mobile, tablet, and desktop
  • SCORM Compliant: Full integration with Learning Management Systems
  • Pure CSS Animations: GPU-accelerated transitions without JavaScript overhead
  • Slot-Based Components: Flexible injection of content and interactive components
  • WCAG 2.1 AA Accessible: Built with accessibility first from the ground up
  • Production-Ready: Tested and optimized for real-world eLearning deployment

Installation

npm install @zomako/elearning-layout-engine

Quick Start

1. Build the library

cd node_modules/@zomako/elearning-layout-engine
npm run build

2. Include in your course

Create an HTML file that references the built assets:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>My Course</title>
  <link rel="stylesheet" href="path/to/elearning-layout-engine/dist/css/main.css">
  <link rel="stylesheet" href="path/to/elearning-layout-engine/dist/css/elearning-components.css">
  <link rel="stylesheet" href="path/to/elearning-layout-engine/dist/css/component-overrides.css">
</head>
<body>
  <div class="viewport">
    <div class="slides">
      <!-- Add your slides here -->
    </div>
  </div>
  <script src="path/to/elearning-layout-engine/dist/js/react.production.min.js"></script>
  <script src="path/to/elearning-layout-engine/dist/js/react-dom.production.min.js"></script>
  <script src="path/to/elearning-layout-engine/dist/js/elearning-components.umd.js"></script>
  <script src="path/to/elearning-layout-engine/dist/js/scorm.js"></script>
  <script src="path/to/elearning-layout-engine/dist/js/main.js"></script>
</body>
</html>

3. Add slides

Insert slides with the .slide class into .slides:

<section class="slide" data-slide-id="slide-1" data-slide-type="content">
  <header class="slide__header">
    <h1>Welcome to the Course</h1>
  </header>
  <main class="slide__body">
    <p>This is the first slide content.</p>
  </main>
  <footer class="slide__footer">
    <button onclick="slideManager.nextSlide()">Next</button>
  </footer>
</section>

Project Structure

elearning-layout-engine/
├── dist/                    # Build output (generated by npm run build)
│   ├── css/
│   │   └── main.css
│   ├── js/
│   │   ├── main.js
│   │   └── scorm.js
│   ├── templates/
│   │   ├── slide.html           # Master template
│   │   ├── content-slide.html
│   │   ├── accordion-slide.html
│   │   ├── dnd-slide.html
│   │   ├── timeline-slide.html
│   │   ├── matching-slide.html
│   │   ├── sorting-slide.html
│   │   ├── quiz-slide.html
│   │   └── branching-slide.html
│   └── index.html
├── src/
│   ├── css/
│   │   └── main.css
│   ├── js/
│   │   ├── main.js
│   │   └── scorm.js
│   ├── templates/
│   └── index.html
├── package.json
└── README.md

Slide Structure

Each slide follows this structure:

| Element | Class | Description | |---------|-------|-------------| | Header | .slide__header | Title and metadata | | Body | .slide__body | Main content (text, media, lists) | | Footer | .slide__footer | Navigation, interaction area | | Interaction Area | .slide__interaction-area | Mount point for interactive components |

Data Attributes

  • data-slide-id – Unique identifier for SCORM lesson location
  • data-slide-typecontent | interaction | assessment
  • data-interaction-type – Type of interaction (see below)
  • data-config – JSON string with component props (for integrated components)

Integrated Components (@zomako/elearning-components)

The layout engine automatically mounts components from @zomako/elearning-components when present. Supported data-interaction-type values:

| Type | Component | Config via data-config | |------|-----------|--------------------------| | accordion | Accordion | {"items":[{"id","title","content"}],"allowMultiple","defaultOpenId"} | | dnd, drag-and-drop | DragAndDropActivity | Component-specific props | | timeline | InteractiveTimeline | Component-specific props | | matching | MatchingActivity | Component-specific props | | sorting | SortingActivity | Component-specific props | | flashcard, quiz | FlashcardDeck | {"cards":[{"front","back"}]} | | branching | BranchingScenario | Component-specific props |

Adaptive Sizing

The layout engine automatically gives interactive components balanced screen space. When a slide has a .slide__interaction-area with data-interaction-type, the interaction area:

  • Uses ~28% of viewport height (min 120px, max 350px) on desktop—kept compact to limit scrolling when content expands
  • Gets a proportional share of the slide grid
  • Scales text for readability without dominating the viewport
  • Adapts on mobile (~24% viewport height) for smaller screens

No extra configuration needed—it activates when data-interaction-type is present.

Component Overrides

component-overrides.css (loaded after elearning-components.css) ensures:

  • Accordion and BranchingScenario components fill the full width of the interaction area (overriding their default max-width)
  • Choice buttons are more compact to reduce vertical scroll

Example with Accordion:

<div class="slide__interaction-area"
  data-interaction-type="accordion"
  data-config='{"items":[{"id":"1","title":"Section 1","content":"Content here"}],"allowMultiple":true}'>
</div>

API Reference

SlideManager (global: window.slideManager)

| Method | Description | |--------|-------------| | showSlide(index) | Show slide by index (0-based) | | nextSlide() | Go to next slide | | previousSlide() | Go to previous slide | | goToSlide(slideId) | Jump to slide by data-slide-id | | getCurrentSlide() | Get the active slide element | | getTotalSlides() | Get total slide count |

SCORM (global: scorm)

| Method | Description | |--------|-------------| | init() | Initialize connection to LMS (auto-called on load) | | finish() | Terminate LMS connection | | get(param) | Get value from SCORM data model | | set(param, value) | Set value in SCORM data model | | commit() | Persist data to LMS | | setStatus(status) | Set lesson status (e.g., "completed") | | setScore(score, maxScore) | Set and commit score | | setLocation(location) | Set current slide ID | | getStatus() | Get lesson status | | getScore() | Get raw score | | getLocation() | Get lesson location | | isInitialized() | Check if SCORM is connected |

Custom Events

mountInteraction

Dispatched when a slide with an interaction area becomes active. Listen to mount custom components:

document.addEventListener('mountInteraction', (e) => {
  const { slideId, interactionType, container } = e.detail;
  // Build and inject your interaction into container
});

interactionCompleted

Dispatch when an interaction is complete to update SCORM score:

document.dispatchEvent(new CustomEvent('interactionCompleted', {
  detail: {
    slideId: 'quiz-1',
    score: 8,
    maxScore: 10
  }
}));

Templates

The master template (slide.html) uses placeholders:

  • {{slideId}} – Unique slide identifier
  • {{slideType}} – content | interaction | assessment
  • {{title}} – Slide title
  • {{content}} – Slide body content
  • {{interactionType}} – Interaction component type

Specialized templates extend this for accordion, quiz, drag-and-drop, matching, sorting, timeline, and branching slides.

SCORM Compliance

The library uses the SCORM 1.2 data model:

  • cmi.core.lesson_status – Lesson status
  • cmi.core.lesson_location – Current slide ID
  • cmi.core.score.raw – Raw score
  • cmi.core.score.max – Maximum score

When no LMS is present, the library runs in standalone mode with console logging.

Accessibility

  • Keyboard navigation – Arrow keys (← →) for slide navigation
  • Focus styles – Visible focus outline on buttons and links
  • Reduced motion – Respects prefers-reduced-motion media query
  • High contrast – Respects prefers-contrast for stronger borders
  • Skip link – Add .skip-link for keyboard users to skip to main content

Testing

A test.html file is included for local verification. After building:

npm run build
npx serve .

Then open http://localhost:3000/test.html in your browser. The test includes sample Accordion and Flashcard slides.

Browser Support

Modern browsers (Chrome, Firefox, Safari, Edge). Uses 100dvh for viewport height—fallback may be needed for older browsers.

License

MIT