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

@get-set/gs-range

v1.0.2

Published

Get-Set Range slider

Downloads

175

Readme

GSRange

A beautiful, dependency-free range slider that ships four ways from a single codebase — a native window.GSRange factory, a jQuery plugin ($.fn.GSRange), an HTMLElement.prototype.GSRange method, and a React <GSRange> component with a typed imperative ref. Single value, dual-thumb range, or N-thumb multiple modes; fill/connect, marks & ticks, tooltips, vertical + RTL orientation, full keyboard + ARIA accessibility, light/dark/auto theming and an accent color.

Features

  • Four usage modes — vanilla factory, jQuery, prototype, and React — all sharing the same actions/ constants/ helpers/ types/.
  • Three modessingle (number), range (two thumbs → tuple), multiple (N thumbs → array).
  • Fill / connect between thumbs (or from the start to a single thumb), with an animated transition.
  • Marks / ticks — boolean, interval, values array, or {value,label}[], with snapToMarks and live tick highlighting.
  • Tooltipsnone / hover / always, custom format function and four placements, with a fade + scale entrance.
  • Vertical orientation and RTL layout.
  • Pushable thumbs with a configurable minimum gap (or plain no-cross).
  • Precision via decimals (inferred from step).
  • Keyboard — Arrow keys, PageUp/PageDown, Home/End (RTL-aware).
  • Accessibilityrole="slider", aria-valuemin/max/now/text, aria-orientation, per-thumb aria-label.
  • Theminglight / dark / auto (follows prefers-color-scheme) plus an accent color; sm / md / lg sizes.
  • Beautiful micro-interactions — thumb grow + lift on grab, ripple ring, animated fill, tooltip fade, tick highlighting — all respecting prefers-reduced-motion.
  • CallbacksonInput (live), onChange, onChangeCommitted.
  • React-only gsx prop for scoped per-instance styles.

Installation

npm i @get-set/gs-range

Package entry points

| Consumer | Resolves to | | ------------------- | ------------------------------ | | import (React/ESM) | dist/components/GSRange.js | | require (CJS/UMD) | dist-js/bundle.js (bundled) | | Types | dist/components/GSRange.d.ts |

The dist-js/bundle.js build attaches window.GSRange, and — when jQuery is present — $.fn.GSRange, plus HTMLElement.prototype.GSRange.

Build

npm run build      # build:js (webpack bundle) + build:react (tsc)
npm run build:js   # dist-js/bundle.js (window + jQuery + prototype)
npm run build:react # dist/ ESM + .d.ts

Tests

npm test

Usage — Native JS (window.GSRange)

The factory accepts a CSS selector string OR a DOM element as its first argument, and returns a ref with the imperative API.

<link rel="stylesheet" href="node_modules/@get-set/gs-range/styles/GSRange.css" />
<div id="volume"></div>
<script src="node_modules/@get-set/gs-range/dist-js/bundle.js"></script>
<script>
  // selector string
  const slider = GSRange('#volume', {
    min: 0,
    max: 100,
    value: 40,
    tooltip: 'hover',
    onInput: (v) => console.log('live', v),
    onChangeCommitted: (v) => console.log('committed', v)
  });

  // …or a DOM element
  const el = document.getElementById('volume');
  GSRange(el, { value: 60 });

  slider.getValue();   // 40
  slider.setValue(75); // clamps + snaps
  slider.reset();
</script>

You can also enhance an existing <input> — it is hidden and its value is mirrored ("40" for single, "20,80" for multi).

The instance registry — window.GSRangeConfigue

Every instance registers itself under its reference (auto-generated when omitted):

GSRange('#volume', { reference: 'vol' });
const ref = window.GSRangeConfigue.instance('vol');
ref.setValue(90);

Usage — jQuery ($.fn.GSRange)

<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script src="node_modules/@get-set/gs-range/dist-js/bundle.js"></script>
<script>
  $('.slider').GSRange({ mode: 'range', value: [20, 80], tooltip: 'always' });
</script>

The adapter iterates the jQuery set and calls the factory with each element (this is why the factory must accept an element, not only a selector).

Usage — Prototype (HTMLElement.prototype.GSRange)

<script src="node_modules/@get-set/gs-range/dist-js/bundle.js"></script>
<script>
  document.getElementById('price').GSRange({ min: 0, max: 1000, step: 50 });
</script>

Usage — React (<GSRange>)

import { useRef } from 'react';
import GSRange, { GSRangeHandle } from '@get-set/gs-range';
import '@get-set/gs-range/styles/GSRange.css';

function Filters() {
  const ref = useRef<GSRangeHandle>(null);

  return (
    <>
      <GSRange
        ref={ref}
        mode="range"
        min={0}
        max={100}
        step={5}
        defaultValue={[20, 80]}
        marks={[
          { value: 0, label: '0%' },
          { value: 50, label: '50%' },
          { value: 100, label: '100%' }
        ]}
        tooltip="hover"
        pushable
        minGap={10}
        onChange={(v) => console.log(v)}
      />
      <button onClick={() => ref.current?.reset()}>Reset</button>
    </>
  );
}

Controlled mode: pass value (+ onChange). Uncontrolled: pass defaultValue.

The imperative ref — GSRangeHandle

| Method | Description | | -------------------------- | ---------------------------------------------- | | getValue() | Current value (number / tuple / array). | | setValue(value) | Set + clamp + snap; fires the callbacks. | | reset() | Restore the initial value. | | destroy() | Remove scoped styles + registry entry. |

The gsx prop (React only)

Scoped, per-instance styles injected as a <style data-key> and removed on unmount:

<GSRange
  gsx={{
    '.gs-range-thumb': { boxShadow: '0 2px 8px rgba(0,0,0,.4)' },
    '.gs-range-connect': { background: 'linear-gradient(90deg,#f00,#00f)' }
  }}
/>

Options

Every option is available in all four modes (React exposes them as props).

| Option | Type | Default | Description | | ------------------- | ------------------------------------------------------------ | ----------- | -------------------------------------------------------------------------- | | reference | string | auto GUID | Registry key / React instance id. | | min | number | 0 | Lowest selectable value. | | max | number | 100 | Highest selectable value. | | step | number | 1 | Snap increment (0 = continuous). | | mode | 'single' \| 'range' \| 'multiple' | 'single' | Number of thumbs / value shape. | | value | number \| [number,number] \| number[] | see below | Current value (controlled in React). | | defaultValue | same as value | see below | Uncontrolled initial value. | | connect | boolean | true | Render the fill between thumbs / from start. | | marks | boolean \| number \| number[] \| {value,label}[] | false | Tick marks. true = every step; number = interval. | | snapToMarks | boolean | false | Snap the thumb to the nearest mark. | | tooltip | 'none' \| 'hover' \| 'always' | 'hover' | Tooltip visibility. | | tooltipFormat | (value, index) => string | String | Tooltip / aria value formatter. | | tooltipPlacement | 'top' \| 'bottom' \| 'left' \| 'right' | 'top' | Tooltip position relative to the thumb. | | vertical | boolean | false | Vertical orientation (bottom = min). | | rtl | boolean | false | Right-to-left (horizontal only). | | disabled | boolean | false | Block interaction + dim. | | readOnly | boolean | false | No change, but not dimmed. | | pushable | boolean | false | Push neighbours instead of crossing. | | minGap | number | 0 | Minimum gap kept between adjacent thumbs. | | decimals | number | from step | Decimal places to round + display. | | keyboardStep | number | step | Arrow-key increment. | | pageStep | number | step * 10 | PageUp/PageDown increment. | | theme | 'light' \| 'dark' \| 'auto' | 'auto' | Color theme (auto = OS preference). | | accentColor | string | #2563eb | Accent color (--gsr-accent). | | size | 'sm' \| 'md' \| 'lg' | 'md' | Component size preset. | | customClass | { root, track, connect, thumb, tooltip, marks, mark } | — | Per-part class overrides. | | className | string | — | Extra class on the root. | | reducedMotion | 'auto' \| boolean | 'auto' | Honor prefers-reduced-motion. | | ariaLabel | string | — | aria-label applied to every thumb. | | ariaLabels | string[] | — | Per-thumb aria-label (indexed). | | gsx | NestedCSS | — | React only — scoped per-instance styles. | | onInput | (value, index) => void | — | Fired live on every drag move / keystroke. | | onChange | (value, index) => void | — | Fired when the value changes. | | onChangeCommitted | (value, index) => void | — | Fired once interaction ends (pointer up / keyboard). |

Default value: min (single), [min, max] (range), evenly spread (multiple). Callback index is the thumb index, or -1 for programmatic changes.

Variant catalogs

mode (3)

| Value | Value shape | Thumbs | | ------------ | -------------------- | ------ | | single | number | 1 | | range | [number, number] | 2 | | multiple | number[] | N |

tooltip (3)

| Value | Behaviour | | -------- | ------------------------------------------------ | | none | No tooltip. | | hover | Fades in on hover / focus / grab. | | always | Permanently visible. |

tooltipPlacement (4)

top · bottom · left · right

size (3)

| Value | Track | Thumb | Font | | ----- | ----- | ----- | ----- | | sm | 4px | 14px | 11px | | md | 6px | 18px | 12px | | lg | 9px | 24px | 13px |

theme (3)

light · dark · auto (follows prefers-color-scheme)

marks forms

| Form | Meaning | | ----------------------- | ---------------------------------------------- | | false | No marks. | | true | A mark at every step. | | number | A mark at this interval. | | number[] | Marks at the given values (label = value). | | {value,label}[] | Fully custom marks with labels. |

Events / callbacks

| Callback | When | | ------------------- | -------------------------------------------------------------- | | onInput | Every pointer-move while dragging, and every keystroke. | | onChange | Whenever the value actually changes. | | onChangeCommitted | Once, when the interaction ends (pointer up / key / setValue). |

Methods (imperative API)

Native ref (returned by the factory / window.GSRangeConfigue.instance):

| Method | Description | | -------------------- | ---------------------------------------- | | getValue() | Current value in the mode shape. | | setValue(value) | Set + clamp + snap; fires callbacks. | | reset() | Restore the initial value. | | setDisabled(on) | Enable / disable the control. | | refresh() | Rebuild from updated params (keeps value).| | destroy() | Tear down + restore the original element. |

React handle (GSRangeHandle): getValue · setValue · reset · destroy.

Examples

Native — price range with marks, dark theme, currency tooltip

GSRange('#price', {
  mode: 'range',
  min: 0,
  max: 5000,
  step: 50,
  value: [1000, 3500],
  theme: 'dark',
  accentColor: '#16a34a',
  marks: 25,
  tooltip: 'always',
  tooltipFormat: (v) => '$' + v.toLocaleString(),
  pushable: true,
  minGap: 250,
  onChangeCommitted: ([lo, hi]) => console.log(lo, hi)
});

React — multiple thumbs (uncontrolled) with a ref

const ref = useRef<GSRangeHandle>(null);

<GSRange
  ref={ref}
  mode="multiple"
  min={0}
  max={100}
  defaultValue={[10, 50, 90]}
  pushable
  minGap={5}
  tooltip="hover"
/>;

// later
ref.current?.setValue([20, 40, 60]);

React — controlled single slider

const [v, setV] = useState(40);

<GSRange value={v} onChange={(next) => setV(next as number)} min={0} max={100} />;

License

ISC