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 🙏

© 2025 – Pkg Stats / Ryan Hefner

hpv-number-stepper

v2.2.1

Published

Zero-dependency JavaScript library for building interactive number/list steppers.

Downloads

28

Readme

HPV Number Stepper

New Feature: Content Selection Control

Added allowContentSelection option to the constructor (default: true). When false and using renderAsHtml: true, the display element has user-select: none applied to prevent text selection, treating it more like a control. The input mode always allows selection for editing.

Example:

new HpvNumberStepper({
  // ... other options
  renderAsHtml: true,
  allowContentSelection: false
});

A zero-dependency JavaScript library for building interactive number steppers with customizable layouts and callbacks.

License Version Dependencies

Screenshots

HPV Number Stepper Example

HPV Number Stepper in Action

HPV List Stepper Example

Features

  • 🚀 Zero dependencies - Pure vanilla JavaScript
  • 🎨 Customizable layout - Arrange buttons and input field in any order
  • 🔢 Flexible value formatting - Custom rendering with callback functions
  • ⌨️ Keyboard support - Arrow keys and Enter key navigation
  • 🎯 Event callbacks - onCreate, onChange, and onRender hooks
  • 📱 Responsive design - Works on desktop and mobile
  • 🧹 Memory safe - Proper cleanup with destroy method

Installation

Direct Download

Download the files and include them in your HTML:

<link rel="stylesheet" href="path/to/number-stepper.css">
<script src="path/to/number-stepper.js"></script>

npm (Coming Soon)

npm install hpv-number-stepper

Quick Start

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="number-stepper.css">
</head>
<body>
    <div id="stepper-container"></div>
    
    <script src="number-stepper.js"></script>
    <script>
        const container = document.getElementById('stepper-container');
        const stepper = new HpvNumberStepper({
            initialValue: 5,
            min: 0,
            max: 100,
            stepSize: 1
        });
        
        stepper.mountTo(container);
    </script>
</body>
</html>

Configuration Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | initialValue | Number | 0 | Starting value for the stepper | | min | Number | 0 | Minimum allowed value | | max | Number | 100 | Maximum allowed value | | stepSize | Number | 1 | Amount to increment/decrement | | layout | Array | ['minus', 'input', 'plus'] | Order of elements | | onCreate | Function | undefined | Callback when stepper is created | | onChange | Function | undefined | Callback when value changes | | onRender | Function | (val) => \${val}%`` | Custom value formatting |

Examples

Basic Usage

const stepper = new HpvNumberStepper({
    initialValue: 10,
    min: 0,
    max: 50,
    stepSize: 5
});

List Stepper (select from items)

Alongside numeric steppers, the library provides a list-based stepper that cycles through a list of items (default shape { id, label }). It preserves the same layout, keyboard, and lifecycle behavior as HpvNumberStepper, but renders the current item label and wraps around when reaching the ends.

Usage

const countries = [
    { id: 'us', label: 'United States' },
    { id: 'ca', label: 'Canada' },
    { id: 'mx', label: 'Mexico' }
];

const stepper = new HpvListStepper({
    items: countries,
    initialItem: 'us', // can be the item key (id) or the full item object
    // keyField/valueField customize which properties identify and display items
    // keyField: 'id',
    // valueField: 'label',
    onRender: (item) => item.label, // defaults to item[valueField]
    onChange: (item, index, instance) => console.log('Selected:', item, index),
    layout: ['minus', 'input', 'plus']
});

stepper.mountTo(document.getElementById('country-stepper'));

Options (additions)

| Option | Type | Default | Description | |--------|------|---------|-------------| | items | Array | [] | Source list of selectable items | | initialItem | object|string| items[0] | Full item object or key value (see keyField) to start selected | | keyField | string | 'id' | Property name used as the unique key for items | | valueField | string | 'label' | Property name used for display and input matching | | onRender | Function | (item, index, instance) => item?.[valueField] || '' | Formats the displayed text for the selected item | | onChange | Function | undefined | Called with (item, index, instance) on selection change |

Notes:

  • Wrap-around is enabled by default: next on last goes to first, previous on first goes to last.
  • Buttons use chevrons by default for list steppers.
  • Keyboard: Up/Down arrows move forward/backward; Enter confirms input.
  • Typing in the input performs a case-insensitive substring match on valueField.

Additional API

  • getSelectedItem() → returns the currently selected item.
  • setSelectedItem(item) → select by providing the full item object (recommended).
  • updateItems(newItems) → replace the items array and keep selection when possible.

Basic Number Stepper

Custom Layout

const stepper = new HpvNumberStepper({
    initialValue: 0,
    layout: ['plus', 'input', 'minus'] // Plus button first
});

Percentage Stepper

const stepper = new HpvNumberStepper({
    initialValue: 25,
    min: 0,
    max: 100,
    stepSize: 0.5,
    onRender: (val) => `${val.toFixed(1)}%`,
    onChange: (val, instance) => {
        console.log(`Value changed to: ${val}%`);
    }
});

Percentage Stepper Example Multi Stepper Example

Currency Stepper

const stepper = new HpvNumberStepper({
    initialValue: 10.00,
    min: 0,
    max: 1000,
    stepSize: 0.25,
    onRender: (val) => `$${val.toFixed(2)}`,
    onChange: (val) => {
        console.log(`Price: $${val.toFixed(2)}`);
    }
});

Input-First Layout

const stepper = new HpvNumberStepper({
    initialValue: 5,
    layout: ['input', 'minus', 'plus'], // Input field first
    onRender: (val) => `${val} items`
});

API Methods

mountTo(element)

Mounts the stepper to a DOM element.

const container = document.getElementById('my-container');
stepper.mountTo(container);

setValue(value)

Programmatically sets the stepper value.

stepper.setValue(25);
stepper.setValue('30.5'); // String values are parsed

getValue(rendered)

Gets the current value.

const rawValue = stepper.getValue(); // Returns number
const displayValue = stepper.getValue(true); // Returns formatted string

destroy()

Cleans up event listeners and removes from DOM.

stepper.destroy();

Keyboard Support

  • Arrow Up - Increment value
  • Arrow Down - Decrement value
  • Enter - Confirm input and remove focus

Styling

The component uses CSS custom properties and can be easily customized:

.stepper-container {
    border: 2px solid #007bff;
    border-radius: 8px;
    font-family: 'Arial', sans-serif;
}

.stepper-button {
    background-color: #f8f9fa;
    color: #007bff;
    font-weight: bold;
}

.stepper-button:hover {
    background-color: #e9ecef;
}

.stepper-input {
    font-size: 16px;
    padding: 8px 12px;
}

Browser Support

  • Chrome 60+
  • Firefox 55+
  • Safari 12+
  • Edge 79+

Development

Building

npm install
npm run build

Project Structure

├── src/
│   ├── js/
│   │   └── number-stepper.js    # Main JavaScript file
│   └── css/
│       └── number-stepper.css   # Styles
├── gulp/                        # Build tasks
├── index.html                   # Demo page
└── package.json

Build System

This project uses Gulp for building:

  • gulp - Build both JS and CSS
  • gulp js - Build JavaScript only
  • gulp css - Build CSS only
  • gulp watch - Watch for changes and rebuild

License

This project is licensed under the Creative Commons Attribution-NonCommercial 4.0 International License.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Author

Danilo T Recchia

Changelog

v1.0.0

  • Initial release
  • Zero-dependency implementation
  • Customizable layouts
  • Keyboard support
  • Event callbacks
  • Memory management