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

mosaique-effects

v1.0.14

Published

Shared JS effects library for LumApps client sites

Readme

Mosaique Effects

Shared JS effects library for LumApps client sites. Loaded via <script> tag — each site enables features through a simple config object.

Quick Start

Add this to the site's header (Settings > Header):

<script>window.MosaiqueConfig = {
  reactions: true,
  scrollReveal: true,
  headings: true,
  cardLift: true,
  imageZoom: true,
  readingProgress: true,
  scrollTop: true,
  buttonEffects: true,
  navHover: true,
  headingAnchors: true
};</script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3/dist/ScrollTrigger.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/mosaique-effects@1/dist/mosaique-effects.min.js"></script>

Set any module to false or remove it to disable that effect.

Manual mode (host-driven)

By default the library self-boots: on DOMContentLoaded it resolves the config (localStorage cache → API → window.MosaiqueConfig) and applies the enabled modules.

A host that already has the resolved config can drive it instead:

window.MosaiqueEffectsManual = true;   // set BEFORE the library runs — stops auto-boot
// ...once the library has loaded and you have the config object:
window.MosaiqueEffects.init(config);   // applies enabled modules (keeps the .front-office guard)

The Mosaique Dashboard extension uses this: it inlines the library (self-hosted, no CDN), resolves the config from the site's global Style, then calls init(). Sites that just <script>-include the library are unaffected — without the flag it auto-boots.

Modules

| Key | Effect | |-----|--------| | reactions | Animated reaction buttons (scale, wiggle, particle burst) | | scrollReveal | Staggered fade-in for content elements on page load and scroll | | headings | Subtle letter-spacing tighten + fade on h1/h2 | | cardLift | Scale + shadow elevation on content list cards on hover | | imageZoom | Gentle zoom on linked images on hover | | readingProgress | Thin accent bar at top of viewport tracking scroll position | | scrollTop | Floating back-to-top button (bottom-left) | | buttonEffects | Click ripple + press bounce on buttons | | navHover | Directional animated underline on main nav links | | headingAnchors | Hover-reveal anchor links on headings, copies URL to clipboard | | slimScrollbars | Minimal, on-brand scrollbars inside widgets (not the page) — CSS only, no GSAP | | cursorGlow | Soft brand-coloured aura following the cursor (Frontier-style; desktop only, no GSAP) |

Adding a new effect

Each effect is one self-contained module. Pick a camelCase key (e.g. tableStripes) — that key links the effect to its dashboard toggle, so keep it stable.

  1. Create the module src/modules/<key>.js:

    import { createTracker, queryAll, injectStyles } from "../core/utils.js";
    import { watch } from "../core/observer.js";
    import css from "./table-stripes.css";      // optional — only if the effect needs CSS
    
    var tracker = createTracker();
    
    function apply() {
      queryAll(".front-office .your-selector").forEach(function (el) {
        if (!tracker.track(el)) return;          // run once per element (survives SPA re-renders)
        // ...attach behaviour, e.g. gsap.to(el, { ... })
      });
    }
    
    export function init() {
      injectStyles("mosaique-table-stripes", css); // omit if no CSS
      watch(".your-selector", apply);              // re-applies on SPA navigation
    }
  2. (optional) CSS src/modules/<key>.css — imported as a string and injected at runtime. Scope rules under .front-office so they never hit the editor.

  3. Register it in src/index.js — import the init and add it to MODULE_MAP under your key:

    import { init as initTableStripes } from "./modules/table-stripes.js";
    // ...
    var MODULE_MAP = {
      // ...existing...
      tableStripes: initTableStripes,   // <-- key drives the config + the dashboard toggle
    };
  4. GSAP? Modules may use the global gsap / ScrollTrigger. If your effect does not need GSAP, add its key to NO_GSAP in src/index.js so it still runs when GSAP is absent (see headingAnchors).

  5. Build: npm run build (updates dist/mosaique-effects.min.js), and add a row to the Modules table above.

  6. Expose the on/off toggle. The switch admins see lives in the Mosaique Dashboard widget, not here — add a MODULE_REGISTRY entry there with the same key. See that repo's ADDING_ENHANCEMENTS.md. Mismatched keys = the toggle saves but nothing runs.

Publishing to npm

The library is hosted on npm and served via jsDelivr CDN.

# First time setup
npm login

# Build
npm run build

# Bump version and publish
npm version patch    # 1.0.0 -> 1.0.1
npm publish

jsDelivr picks up new versions automatically. Sites reference a specific version in their script tag, so updating the npm version doesn't break existing sites until you update their header.

Version pinning:

  • mosaique-effects@1 — exact version, never changes
  • [email protected] — latest patch within 1.0.x
  • mosaique-effects@1 — latest minor within 1.x.x

Local Development

npm install
npm run build          # Build dist/mosaique-effects.min.js
npm run serve          # Serve on http://localhost:8081

For testing, point the site header to http://localhost:8081/mosaique-effects.min.js instead of the CDN URL.

Architecture

  • src/index.js — entry point, reads config, boots enabled modules
  • src/core/observer.js — shared MutationObserver for React SPA re-renders
  • src/core/utils.js — WeakSet tracker, queryAll, CSS injection
  • src/modules/*.js — individual effect modules
  • src/modules/*.css — module CSS (embedded in JS at build time)

Each module:

  • Exports an init() function called by the entry point
  • Registers DOM selectors with the shared observer
  • Uses WeakSet tracking to avoid double-initialising elements
  • Injects its own CSS via <style> tag at runtime

GSAP is a peer dependency loaded separately (CDN, or self-hosted/inlined by the host) — not bundled.

CSS Variables

Some modules use LumApps CSS variables for theming:

  • --lumx-color-secondary-N — accent colour for reading progress bar and scroll-to-top button

Safety

  • All effects are scoped to .front-office so they don't run in the LumApps editor
  • Scroll reveal has a CSS animation fallback — if GSAP fails, content auto-reveals after 1.5s
  • Headings have a similar safety fallback after 3s
  • The library checks for GSAP and degrades gracefully if not loaded