@preline/input-number
v4.2.0
Published
Preline UI is an open-source set of prebuilt UI components based on the utility-first Tailwind CSS framework.
Readme
Input Number
Input Number - input idea for Shop systems or so.
Contents
Overview
The Input Number component provides a numeric input field with increment and decrement buttons. It's ideal for quantity selectors, cart systems, or any interface requiring numeric input with step controls.
Key Features:
- Numeric input with step controls
- Increment/decrement buttons
- Min/max value constraints
- Custom step values
- Programmatic control via JavaScript API
- Event system for value tracking
- Disabled state support
Installation
To get started, install Input Number plugin via npm, else you can skip this step if you are already using Preline UI as a package.
npm i @preline/input-numberCSS
Use @source to register the plugin's JavaScript path for Tailwind CSS scanning, then @import the plugin's CSS files into your Tailwind CSS file.
@import "tailwindcss";
/* @preline/input-number */
@source "../node_modules/@preline/input-number/*.js";
@import "./node_modules/@preline/input-number/variants.css";
@import "./node_modules/@preline/input-number/theme.css";JavaScript
Include the JavaScript that powers the interactive elements near the end of your </body> tag:
<script src="./node_modules/@preline/input-number/index.js"></script>Manual Initialization
Use the non-auto entry if you need manual initialization. In this mode, automatic initialization on page load is not included, so the component should be initialized explicitly.
<script type="module">
import HSInputNumber from "@preline/input-number/non-auto.mjs";
new HSInputNumber(document.querySelector("#input-number"));
</script>Via Bundler
When using a bundler (Vite, webpack, etc.), import the plugin directly as an ES module.
@preline/input-number is the auto-init entry: it scans the DOM and initializes matching elements automatically.
import "@preline/input-number";@preline/input-number/non-auto is the manual entry: use it when you want explicit control over when initialization happens, either via autoInit() or by creating a specific instance yourself.
import HSInputNumber from "@preline/input-number/non-auto";
HSInputNumber.autoInit();
// Or initialize a specific element manually
const el = document.querySelector("#input-number");
if (el) new HSInputNumber(el);TypeScript
This package ships with TypeScript type definitions. No additional @types/ package is needed.
Basic usage
The following example demonstrates the minimal HTML structure required for an input number component. This is a base template without custom styling - you can apply your own CSS classes and styles as needed. The component includes an input field and increment/decrement buttons.
<div data-hs-input-number>
<input type="text" aria-roledescription="Number field" value="1" data-hs-input-number-input>
<button type="button" class="" tabindex="-1" aria-label="Decrease" data-hs-input-number-decrement>
Minus
</button>
<button type="button" class="" tabindex="-1" aria-label="Increase" data-hs-input-number-increment>
Add
</button>
</div>Structure Requirements:
data-hs-input-number: Required on the container elementdata-hs-input-number-input: Required on the input elementdata-hs-input-number-increment: Required on the increment buttondata-hs-input-number-decrement: Required on the decrement button- Proper ARIA attributes (
aria-roledescription,aria-label)
Initial State:
- Input field contains the initial value (e.g.,
value="1") - Buttons are enabled/disabled based on min/max constraints
Configuration Options
Data Options
Data options are specified in the data-hs-input-number attribute.
| Attribute | Target Element | Type | Default | Description |
| --- | --- | --- | --- | --- |
| data-hs-input-number | Container | - | - | Activate an Input Number by specifying on an element. Should be added to the container. |
| :min | Inside data-hs-input-number | number | "-Infinity" | 0 | Defines the minimum possible value. -Infinity allows you to enter negative values without restrictions. |
| :max | Inside data-hs-input-number | number | null | null | Defines the maximum possible value. null means no maximum limit. |
| :step | Inside data-hs-input-number | number | 1 | Determines the step by which the value will increase or decrease when buttons are clicked. |
| :forceBlankValue | Inside data-hs-input-number | boolean | false | Whether the input value should be blank when the value isn't set. When true, empty input shows blank instead of default value. |
Example:
<div data-hs-input-number='{
"min": 0,
"max": 100,
"step": 5,
"forceBlankValue": false
}'>
<!-- Input and buttons -->
</div>Required CSS Classes / Data Attributes
These data attributes define the structure and must be present for the input number to function.
| Data Attribute | Required On | Purpose |
| --- | --- | --- |
| data-hs-input-number-input | Input element | Identifies the numeric input field |
| data-hs-input-number-increment | Button element | Identifies the increment button |
| data-hs-input-number-decrement | Button element | Identifies the decrement button |
Tailwind Modifiers
| Name | Description |
| --- | --- |
| hs-input-number-disabled:* | A modifier that allows you to set Tailwind classes when input's value is set to zero (or minimum value). |
JavaScript API
The HSInputNumber object is available in the global window object after the plugin is loaded.
Instance Methods
These methods are called on an input number instance.
| Method | Parameters | Return Type | Description |
| --- | --- | --- | --- |
| destroy() | None | void | Destroys the input number instance, removes all generated markup, classes, and event listeners. Use when removing input number from DOM. |
Static Methods
These methods are called directly on the HSInputNumber class.
| Method | Parameters | Return Type | Description |
| --- | --- | --- | --- |
| HSInputNumber.getInstance(target, isInstance) | target: HTMLElement \| string (CSS selector)isInstance: boolean (optional) | HSInputNumber \| { id: number, element: HSInputNumber } \| null | Returns the input number instance associated with the target. If isInstance is true, returns collection item object { id, element } where element is the HSInputNumber instance. If isInstance is false or omitted, returns the HSInputNumber instance directly. Returns null if input number instance is not found. |
Usage Examples
Example 1: Destroying input number instance
const instance = HSInputNumber.getInstance('#hs-input-number', true);
if (instance) {
const { element } = instance;
const destroyBtn = document.querySelector('#hs-destroy-btn');
destroyBtn.addEventListener('click', () => {
element.destroy();
});
}Example 2: Getting instance and accessing properties
// Get the input number instance
const instance = HSInputNumber.getInstance('#hs-input-number', true);
if (instance) {
const { element } = instance;
// Access instance properties
console.log('Current value:', element.inputValue);
console.log('Min value:', element.minInputValue);
console.log('Max value:', element.maxInputValue);
console.log('Step:', element.step);
// Clean up when removing from DOM
function removeInputNumber() {
element.destroy();
}
}Example 3: Destroying input number instance
const instance = HSInputNumber.getInstance('#hs-input-number', true);
if (instance) {
const { element } = instance;
const removeBtn = document.querySelector('#hs-remove-btn');
removeBtn.addEventListener('click', () => {
// Clean up before removing from DOM
element.destroy();
// Now safe to remove the element
document.querySelector('#hs-input-number').remove();
});
}Events
Input number instances emit events that can be listened to for value tracking and custom behavior.
| Event Name | When Fired | Callback Parameter | Description |
| --- | --- | --- | --- |
| on:change | When input value was changed | { inputValue: number } | Fires when the input value changes (via buttons or direct input). Returns an object with the inputValue containing the current numeric value. |
Event Usage Example
// Get input number instance
const instance = HSInputNumber.getInstance('#hs-input-number', true);
if (instance) {
const { element } = instance;
// Listen to change event
element.on('change', ({ inputValue }) => {
console.log('Input value changed:', inputValue);
// Perform actions after value changes
// e.g., update cart, calculate totals, validate
});
}Common Patterns
Pattern 1: Quantity Selector
Create a quantity selector for shopping carts.
<div data-hs-input-number='{
"min": 1,
"max": 99,
"step": 1
}'>
<input type="text" value="1" data-hs-input-number-input>
<button data-hs-input-number-decrement>-</button>
<button data-hs-input-number-increment>+</button>
</div>Pattern 2: Negative Values Allowed
Allow negative values by setting min to -Infinity.
<div data-hs-input-number='{
"min": "-Infinity",
"max": null,
"step": 1
}'>
<!-- Input and buttons -->
</div>Pattern 3: Handling Value Changes
Track value changes with event listener.
<div id="hs-input-number-first" data-hs-input-number>
<input type="text" value="1" data-hs-input-number-input>
<button data-hs-input-number-decrement>-</button>
<button data-hs-input-number-increment>+</button>
</div>
<script>
const instance = HSInputNumber.getInstance('#hs-input-number-first', true);
if (instance) {
const { element } = instance;
element.on('change', ({ inputValue }) => {
console.log('Quantity:', inputValue);
// Update cart or perform other actions
});
}
</script>License
Copyright (c) 2026 Preline Labs.
Licensed under the MIT License.
