UNPKG

preline

Version:

Preline UI is an open-source set of prebuilt UI components based on the utility-first Tailwind CSS framework.

329 lines (240 loc) 10.9 kB
# Input Number Input Number - input idea for Shop systems or so. [![npm](https://img.shields.io/badge/npm-v4.2.0-blue)](https://www.npmjs.com/package/@preline/input-number) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) [![Demo](https://img.shields.io/badge/demo-online-brightgreen)](https://preline.co/plugins/input-number.html) ## Contents - [Overview](#overview) - [Installation](#installation) - [Basic usage](#basic-usage) - [Configuration Options](#configuration-options) - [JavaScript API](#javascript-api) - [Events](#events) - [Common Patterns](#common-patterns) - [License](#license) ## 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. ```bash npm i @preline/input-number ``` ### CSS Use [`@source`](https://tailwindcss.com/docs/functions-and-directives#source-directive) to register the plugin's JavaScript path for Tailwind CSS scanning, then [`@import`](https://tailwindcss.com/docs/functions-and-directives#import-directive) the plugin's CSS files into your Tailwind CSS file. ```css @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: ```html <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. ```html <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. ```js 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. ```js 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. ```html <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 element - `data-hs-input-number-input`: Required on the input element - `data-hs-input-number-increment`: Required on the increment button - `data-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:** ```html <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)<br>`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** ```javascript 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** ```javascript // 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** ```javascript 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 ```javascript // 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. ```html <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. ```html <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. ```html <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](https://opensource.org/licenses/MIT).