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

@3nvs/polyfront-slider

v1.1.4

Published

A modern, accessible TypeScript Web Component slider supporting horizontal, vertical, and range modes with ticks, labels, tooltips, and form integration.

Downloads

30

Readme

🎛️ @3nvs/polyfront-slider (v1.1.4)

npm (scoped) license Storybook CI

The official scoped package for the Polyfront Slider Web Component — built with TypeScript, accessible, framework-agnostic, and optimized for modern apps.


✨ Overview

polyfront-slider is an open-source Web Component slider that works in React, Vue, Angular, Svelte, or plain HTML/JS.

It provides enterprise-grade configurability, theming tokens, accessibility, and form integration — all in a single, dependency-free package.


🚀 Key Features

| Category | Highlights | |-----------|-------------| | 🎨 UI/UX | OKLCH color system, dark mode, hover/active/focus states, large touch targets, and elevation shadows. | | 🧩 Configurable | Supports {min, max, step} or discrete arrays like [0,1500,1600,…]. Auto-detects step size and disables missing values. | | 🧱 Modes | Single or dual-thumb (range) slider. | | 🧠 Smart Logic | Auto GCD step detection, blocked intervals, minimum thumb distance. | | ♿ Accessible | Full WAI-ARIA compliance, keyboard navigation, and form-associated support. | | 🖥️ Responsive | 100 % width, mobile-friendly, fits any layout. | | 🌗 Themeable | Size presets (sm,md,lg), CSS tokens, and dark/light mode support. | | 🧪 Reliable | TypeScript + Vitest + Storybook 8.6 + GitHub CI. | | 🧰 Reusable | Works standalone or via npm import in any framework. |


🧩 Installation

# Scoped (recommended)
npm install @3nvs/polyfront-slider

# or use alias (unscoped)
npm install polyfront-slider

🧑‍💻 Usage

🚀 Quick Start

1️⃣ Register the component

import { definePolyfrontSlider } from '@3nvs/polyfront-slider';
definePolyfrontSlider();

2️⃣ Add to your HTML / JSX

<polyfront-slider id="price-slider" style="inline-size:100%;max-inline-size:480px"></polyfront-slider>

3️⃣ Configure dynamically

const slider = document.getElementById('price-slider');
slider.setConfig({
  mode: 'range',
  orientation: 'horizontal',
  size: 'md',
  values: [0,1500,1600,1700,1800,1900,2000],
  showTicks: true,
  showLabels: true,
  showTooltip: true,
  tickEvery: 1,
  disableMissingSteps: true,
  blockedIntervals: [[1600,1699]],
  minThumbDistance: 1,
  name: 'price'
});

🎯 Helper Functions (Recommended)

For easier usage across frameworks, use these helper functions:

Range Slider

import { createRangeSlider } from '@3nvs/polyfront-slider';

const priceSlider = createRangeSlider(0, 2000, 100);
document.body.appendChild(priceSlider);

Volume Control

import { createVolumeControl } from '@3nvs/polyfront-slider';

const volumeControl = createVolumeControl(100);
volumeControl.style.height = '200px';
document.body.appendChild(volumeControl);

Price Slider with Discrete Values

import { createPriceSlider } from '@3nvs/polyfront-slider';

const priceSlider = createPriceSlider([0, 1500, 1600, 1700, 1800, 1900, 2000]);
document.body.appendChild(priceSlider);

Discrete Value Slider (Sizes, Ratings, etc.)

import { createDiscreteSlider } from '@3nvs/polyfront-slider';

// Size selector
const sizeSlider = createDiscreteSlider(['XS', 'S', 'M', 'L', 'XL', 'XXL'], 'single');
document.body.appendChild(sizeSlider);

// Rating range
const ratingSlider = createDiscreteSlider([1, 2, 3, 4, 5], 'range');
document.body.appendChild(ratingSlider);

🎨 React-Style Props

import { createSliderWithProps } from '@3nvs/polyfront-slider';

const slider = createSliderWithProps({
  mode: 'range',
  min: 0,
  max: 100,
  step: 5,
  showTooltip: true,
  onChange: (value) => console.log('Value changed:', value),
  onInput: (value) => console.log('Value input:', value),
  className: 'my-slider',
  style: { width: '100%', margin: '20px 0' },
  id: 'my-slider'
});
document.body.appendChild(slider);

🎭 Event Handling

const slider = document.getElementById('my-slider');

// Listen for value changes
slider.addEventListener('polyfront-slider-change', (e) => {
  console.log('Final value:', e.detail.value);
});

// Listen for real-time input
slider.addEventListener('polyfront-slider-input', (e) => {
  console.log('Current value:', e.detail.value);
});

// Get current value
const currentValue = slider.getValue();
console.log('Current value:', currentValue);

// Set value programmatically
slider.setValue([20, 80]); // For range slider
slider.setValue(50); // For single slider

🎨 Framework Integration Examples

React

import { useEffect, useRef } from 'react';
import { definePolyfrontSlider, createSliderWithProps } from '@3nvs/polyfront-slider';

// Register once
definePolyfrontSlider();

function PriceSlider({ onChange }: { onChange: (value: number[]) => void }) {
  const sliderRef = useRef<HTMLElement>(null);

  useEffect(() => {
    if (sliderRef.current) {
      const slider = createSliderWithProps({
        mode: 'range',
        min: 0,
        max: 2000,
        step: 100,
        showTooltip: true,
        onChange: onChange,
        style: { width: '100%' }
      });
      
      sliderRef.current.appendChild(slider);
      
      return () => {
        sliderRef.current?.removeChild(slider);
      };
    }
  }, [onChange]);

  return <div ref={sliderRef} />;
}

Vue 3

<template>
  <div ref="sliderContainer" />
</template>

<script setup lang="ts">
import { onMounted, onUnmounted, ref } from 'vue';
import { definePolyfrontSlider, createSliderWithProps } from '@3nvs/polyfront-slider';

definePolyfrontSlider();

const sliderContainer = ref<HTMLElement>();
let slider: HTMLElement;

onMounted(() => {
  if (sliderContainer.value) {
    slider = createSliderWithProps({
      mode: 'range',
      min: 0,
      max: 100,
      step: 5,
      showTooltip: true,
      onChange: (value) => emit('change', value)
    });
    sliderContainer.value.appendChild(slider);
  }
});

onUnmounted(() => {
  slider?.remove();
});

const emit = defineEmits<{
  change: [value: number[]]
}>();
</script>

Angular

import { Component, ElementRef, OnInit, OnDestroy } from '@angular/core';
import { definePolyfrontSlider, createSliderWithProps } from '@3nvs/polyfront-slider';

@Component({
  selector: 'app-price-slider',
  template: '<div #sliderContainer></div>'
})
export class PriceSliderComponent implements OnInit, OnDestroy {
  @ViewChild('sliderContainer', { static: true }) container!: ElementRef;
  private slider?: HTMLElement;

  ngOnInit() {
    definePolyfrontSlider();
    
    this.slider = createSliderWithProps({
      mode: 'range',
      min: 0,
      max: 2000,
      step: 100,
      showTooltip: true,
      onChange: (value) => this.onValueChange(value)
    });
    
    this.container.nativeElement.appendChild(this.slider);
  }

  ngOnDestroy() {
    this.slider?.remove();
  }

  onValueChange(value: number[]) {
    console.log('Value changed:', value);
  }
}

Svelte

<script lang="ts">
  import { onMount, onDestroy } from 'svelte';
  import { definePolyfrontSlider, createSliderWithProps } from '@3nvs/polyfront-slider';
  
  let sliderContainer: HTMLElement;
  let slider: HTMLElement;

  onMount(() => {
    definePolyfrontSlider();
    
    slider = createSliderWithProps({
      mode: 'range',
      min: 0,
      max: 100,
      step: 5,
      showTooltip: true,
      onChange: (value) => console.log('Value:', value)
    });
    
    sliderContainer.appendChild(slider);
  });

  onDestroy(() => {
    slider?.remove();
  });
</script>

<div bind:this={sliderContainer} />

⚙️ Config Options

| Option | Type | Default | Description | |---------|------|----------|-------------| | mode | 'single' \| 'range' | 'single' | Enables range (2 thumbs) or single thumb. | | orientation | 'horizontal' \| 'vertical' | 'horizontal' | Slider direction. | | size | 'sm' \| 'md' \| 'lg' | 'md' | Track and thumb size preset. | | values | Array<number \| string \| object> | — | Discrete slider values. | | min / max / step | number | — | Continuous slider range. | | disableMissingSteps | boolean | true | Disables non-defined steps. | | blockedIntervals | [number,number][] | [] | Disable ranges of values. | | minThumbDistance | number | 0 | Minimum thumb distance in range mode. | | showTicks | boolean | false | Displays tick marks. | | showLabels | boolean | false | Displays tick labels. | | showTooltip | boolean | false | Shows tooltips for thumb values. | | tickEvery | number | 1 | Render every N-th tick/label. | | rtl | boolean | false | Right-to-left layout support. | | ariaLabel* | string | — | Accessibility labels. | | name | string | — | Enables form submission via JSON value. |


🎨 Theming & Custom Styles

polyfront-slider {
  --pf-color-fill: oklch(0.63 0.21 35);
  --pf-color-fill-strong: oklch(0.56 0.22 35);
  --pf-color-thumb-border: oklch(0.63 0.21 35);
  --pf-track-size: 10px;
  --pf-thumb-size: 28px;
  --pf-focus: 0 0 0 4px color-mix(in oklab, var(--pf-color-fill) 35%, transparent);
}

✅ Supports dark mode (prefers-color-scheme: dark) and reduced motion.


🧪 Testing

npm run test

Example:

import { PolyfrontSlider } from '@3nvs/polyfront-slider';

const el = new PolyfrontSlider();
el.setConfig({ min: 0, max: 100, step: 10, mode: 'range' });
el.setValue([20, 80]);
expect(el.getValue()).toEqual([20, 80]);

📘 Storybook Demo

Local preview:

npm run storybook

Live demo → https://nirmalsamaranayaka.github.io/polyfront-slider


🏗️ Build

npm run build

Outputs:

dist/
├─ index.mjs
├─ index.cjs
└─ index.d.ts

⚙️ CI / CD via GitHub Actions

| Workflow | Trigger | Purpose | |-----------|----------|---------| | ci.yml | Push/PR → main | Type check, test, build verification | | storybook.yml | Push → main | Deploys Storybook to GitHub Pages | | release.yml | Tag push (v*.*.*) | Auto-publishes to npm (requires NPM_TOKEN) |


📁 Folder Structure

polyfront-slider/
├─ dist/                            ← build output (from @3nvs/polyfront-slider)
├─ src/
│  ├─ index.ts
│  └─ polyfront-slider.ts
├─ tests/                           ← Vitest tests
│  └─ polyfront-slider.test.ts
├─ stories/                          ← Storybook config
│  └─ polyfront-slider.stories.ts
├─ .storybook/
├─ .github/workflows/                ← CI workflows (ci.yml, storybook.yml, etc.)
├─ tsup.config.ts
├─ tsconfig.json
├─ packages/                        ← workspace packages
│  ├─ slider/                       ← canonical scoped package (@3nvs/polyfront-slider)
│  │   ├─ CHANGELOG.md
│  │   └─ package.json
│  └─ slider-shim/                  ← unscoped alias (polyfront-slider)
│      ├─ CHANGELOG.md
│      ├─ index.cjs
│      ├─ index.mjs
│      ├─ index.d.ts
│      └─ package.json
├─ LICENSE
├─ .npmrc                           ← optional npm scope config
└─ package.json                     ← workspace root (private)
└─ README.md

🌍 Publishing to npm

npm run build
npm version patch
npm publish --access public

👨‍💻 Author

Nirmal Samaranayaka
📧 [email protected]
💼 https://github.com/NirmalSamaranayaka


🪪 License

MIT © 2025 Nirmal Samaranayaka
See LICENSE for details.