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

@tacman1123/collection-slider

v0.1.0

Published

A dependency-free, framework-agnostic value slider (Fortepan.hu-style year ruler) that drives a live-following thumbnail carousel (fortepan.us-style). Two custom elements, zero build step required.

Readme

@tacman1123/collection-slider

A dependency-free value slider (<collection-slider>, a Fortepan.hu-style year ruler with a count badge) paired with a live-following thumbnail carousel (CollectionCarousel, fortepan.us-style). Two plain custom elements / classes, zero build step, zero framework requirement.

Trivial setup

No npm install required to try it — import straight from a CDN or a local copy as native ESM:

<script type="module">
  import { CollectionCarousel } from 'https://unpkg.com/@tacman1123/collection-slider/index.js';
  // importing collection-slider.js (directly or via the barrel) registers <collection-slider>
  // as a side effect — no separate customElements.define() call needed.
</script>

<collection-slider min="1900" max="1988" value="1954"></collection-slider>
<div id="thumbnails"></div>
<img id="main-image" alt="">

<script type="module">
  import { CollectionCarousel } from 'https://unpkg.com/@tacman1123/collection-slider/index.js';

  new CollectionCarousel({
    root: document.querySelector('#thumbnails'),
    image: document.querySelector('#main-image'),
    slider: document.querySelector('collection-slider'),
    slides: [
      { value: 1954, thumb: 'https://example.test/thumb-1.jpg', id: 'FI001' },
      { value: 1954, thumb: 'https://example.test/thumb-2.jpg', id: 'FI002' },
      // ...
    ],
  });
</script>

That's the entire integration. No build tool, no bundler config, no framework adapter.

With npm

npm install @tacman1123/collection-slider
import { CollectionSlider, CollectionCarousel } from '@tacman1123/collection-slider';

Works identically inside a bundler, inside Symfony AssetMapper's importmap, or as a raw <script type="module"> tag — the package has no build-time dependencies of its own.

Demo & examples

All of these are static files — no build, no server-side dependency (demo/ uses php -S only because that's a one-liner for a local static server; any static file server works).

| | What it shows | |---|---| | demo/ | The full, realistic case: a year slider + synced photo carousel, driven by real per-year counts from a live photo archive (synthetic placeholder thumbnails, since the demo has no image backend of its own). | | examples/minimal/ | CollectionSlider completely alone — no carousel, just the raw collection-slider-change event, to show the element has no dependency on the rest of the package. | | examples/generic-data/ | Proof the package isn't photo-specific: the same slider/counts mechanism driving a synthetic rainfall-by-year reading instead of an image. |

cd demo && php -S 127.0.0.1:8080          # then open /index.html
cd examples/minimal && php -S 127.0.0.1:8081
cd examples/generic-data && php -S 127.0.0.1:8082

<collection-slider> attributes

| Attribute | Meaning | |---|---| | min, max, value, step | Standard numeric range, same semantics as <input type="range"> | | tick-count | How many ruler ticks to draw | | counts | JSON-encoded { "value": count } map — renders as "value · count" in the pill labels. Can also be set as a JS property: sliderEl.counts = { 1954: 35 } |

Events

collection-slider-change (bubbles, composed) fires with detail: { value, min, max, percent } on every whole-value change while dragging, not only on release — this is what lets a paired carousel glide with the knob instead of jumping once at the end of a drag. A separate collection-slider-input event fires alongside it during drag for consumers that want the distinction.

CollectionCarousel API

const carousel = new CollectionCarousel({
  root,          // container element — its children are replaced with the rendered strip
  slides,        // [{ value, thumb, id?, alt? }, ...], ordered by value
  image,         // optional <img> to update with the active slide
  indexLabel,    // optional element to receive "N / total" text
  slider,        // optional <collection-slider> to sync with (listens for collection-slider-change)
  gap,           // optional CSS gap between thumbnails, default '0.5rem'
  thumbSize,     // optional thumbnail width, default '72px'
});

carousel.show(index);        // jump to a slide by index
carousel.next();
carousel.previous();
carousel.indexForValue(1954); // nearest slide index for a given slider value

Framework notes

Custom elements work natively in React, Vue, Svelte, and Angular — no wrapper component is required to render <collection-slider> itself. Two things worth knowing:

  • counts as a prop: most frameworks pass unrecognized lowercase props/attrs straight through as HTML attributes, so <collection-slider counts={JSON.stringify(data)}> works the same way the plain-HTML attribute does. If your framework's custom-element interop instead tries to set it as a JS property with an object/Map directly, that also works — counts has both an attribute and a property path (see above).
  • Events: collection-slider-change is a normal CustomEvent, so addEventListener (via a ref/onMount-style hook) is the reliable cross-framework way to listen — JSX-style onCollectionSliderChange-type prop listeners are not standardized for custom events across frameworks the way they are for built-in DOM events.

Origin

Built for Museado/OpenFoto's photo-archive timeline (a Fortepan.hu-style year ruler driving a fortepan.us-style live thumbnail strip), then extracted here so it isn't tied to that project's backend (folio-bundle/Symfony) — same "no local build step for consuming apps" principle as TimelineJS's modern runtime.