Skip to content

Touch-friendly numeric spinner for React, Tailwind, and vanilla JavaScript

License

Notifications You must be signed in to change notification settings

istvan-ujjmeszaros/touchspin

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Repository files navigation

TouchSpin v5

Formerly Bootstrap TouchSpin — Now a modern ESM-first monorepo

Sponsor

TouchSpin (formerly Bootstrap TouchSpin) is a modern rewrite of the popular spinner component. The v5 line ships as an ESM-first monorepo with framework-specific packages so you can pick the delivery mode that fits your stack—core logic, renderer bundles, a jQuery bridge, or a Web Component.

💖 Support This Project

TouchSpin v5 represents nearly 1,000 hours of development work — a complete ground-up rewrite to bring modern ESM architecture, tree-shaking, and multi-framework support to this popular component.

⭐ Become a Sponsor to help sustain ongoing development, faster bug fixes, and new features.

Your sponsorship keeps this project:

  • Free and open-source for everyone
  • 🚀 Actively maintained with regular updates
  • 🐛 Well-tested with comprehensive test coverage
  • 📚 Well-documented with migration guides

Every contribution, no matter the size, makes a real difference!


Packages at a Glance

PackagePurposePrimary EntryBundled Assets
@touchspin/coreFramework-agnostic logic + renderer contractsdist/index.js (ESM)Declarations only
@touchspin/standaloneStandalone mount API (core + renderer)dist/index.js (ESM)Per-renderer subpaths (dist/bootstrapX.js)
@touchspin/jqueryDrop-in jQuery wrapperdist/index.js (ESM)dist/umd/jquery.touchspin-*.umd.js globals
@touchspin/webcomponent<touchspin-input> custom elementPer-renderer subpathsdist/umd/*.touchspin.umd.js globals
@touchspin/renderer-bootstrap3Bootstrap 3 renderer + CSSdist/index.js (ESM)dist/touchspin-bootstrap3.css
@touchspin/renderer-bootstrap4Bootstrap 4 renderer + CSSdist/index.js (ESM)dist/touchspin-bootstrap4.css
@touchspin/renderer-bootstrap5Bootstrap 5 renderer + CSSdist/index.js (ESM)dist/touchspin-bootstrap5.css
@touchspin/renderer-tailwindTailwind-friendly rendererdist/index.js (ESM)dist/touchspin-tailwind.css
@touchspin/renderer-vanillaFramework-free renderer + themedist/index.js (ESM)dist/touchspin-vanilla.css, dist/themes/vanilla.css

All packages declare "type": "module", target Node 22 (the configuration used for builds), and include licenses in the published tarballs. Renderer packages list their CSS under files and expose the stylesheet via exports."./css".

Framework Adapters (Separate Repositories)

Framework-specific adapters are maintained in separate repositories with native tooling:

These adapters are independently versioned to match core compatibility. React and Angular are currently in alpha while Vue and Svelte are stable.

Quick Install

Standalone Adapter (Recommended)

The simplest way to use TouchSpin with a mount API:

npm install @touchspin/standalone
import{mount}from'@touchspin/standalone/bootstrap5';constapi=mount('#quantity',{min: 0,max: 100,step: 1,cancelable: true// Enable cancelable change events});// Listen to eventsconstinput=document.querySelector('#quantity');input.addEventListener('change:start',(event)=>{// Prevent change if neededif(someCondition){event.preventDefault();}});input.addEventListener('speedchange',(event)=>{console.log('Speed changed to:',event.detail.speed);});

Browser via CDN (ESM):

<linkrel="stylesheet" href="https://cdn.jsdelivr.net/npm/@touchspin/renderer-bootstrap5@5/dist/touchspin-bootstrap5.css"><scripttype="module">import{mount}from'https://cdn.jsdelivr.net/npm/@touchspin/standalone@5/dist/bootstrap5.js';mount('#quantity',{min: 0,max: 100});</script>

Modern (ESM) projects

For advanced use with direct core access:

npm install @touchspin/core @touchspin/renderer-bootstrap5
import{TouchSpin}from'@touchspin/core';importBootstrap5Rendererfrom'@touchspin/renderer-bootstrap5';import'@touchspin/renderer-bootstrap5/css';constinput=document.querySelector('#quantity');TouchSpin(input,{renderer: Bootstrap5Renderer,min: 0,max: 100,step: 1,cancelable: true// Enable cancelable change events});// Listen to eventsinput.addEventListener('change:start',(event)=>{// Can prevent the changeevent.preventDefault();});

jQuery integration

npm install @touchspin/jquery jquery

UMD (Browser):

<scriptsrc="https://code.jquery.com/jquery-3.7.1.min.js"></script><scriptsrc="https://cdn.jsdelivr.net/npm/@touchspin/jquery@5/dist/umd/jquery.touchspin-bootstrap5.umd.js"></script><script>// Canonical (recommended)$('#quantity').touchspin({min: 0,max: 100});// Legacy alias (still supported)$('#quantity').TouchSpin({min: 0,max: 100});</script>

ESM:

import{autoInstall}from'@touchspin/jquery';import{mount}from'@touchspin/standalone/bootstrap5';import$from'jquery';autoInstall(mount);$('#quantity').touchspin({min: 0,max: 100});

Web Component

npm install @touchspin/webcomponent
import'@touchspin/webcomponent/bootstrap5';
<touchspin-inputmin="0" max="100" value="42"></touchspin-input>

React

npm install @touchspin/react react react-dom

Controlled:

import{useState}from'react';importTouchSpinfrom'@touchspin/react/bootstrap5';functionApp(){const[value,setValue]=useState(50);return<TouchSpinvalue={value}onChange={setValue}min={0}max={100}/>;}

Uncontrolled:

importTouchSpinfrom'@touchspin/react/vanilla';<TouchSpindefaultValue={25}onChange={(val)=>console.log(val)}/>

Imperative API:

import{useRef}from'react';importTouchSpinfrom'@touchspin/react/tailwind';importtype{TouchSpinHandle}from'@touchspin/react/tailwind';constref=useRef<TouchSpinHandle>(null);<TouchSpinref={ref}defaultValue={10}/>ref.current?.increment();

Per-renderer imports:bootstrap3, bootstrap4, bootstrap5, tailwind, vanillaSSR-safe: Works with Next.js, Remix, and other React frameworks Example app:touchspin-react-example

See the @touchspin/react repository for complete API documentation.

Angular

npm install @touchspin/angular @angular/core @angular/common @angular/forms

Template-driven forms:

import{Component}from'@angular/core';import{FormsModule}from'@angular/forms';import{TouchSpinBootstrap5Component}from'@touchspin/angular/bootstrap5'; @Component({selector: 'app-example',standalone: true,imports: [FormsModule,TouchSpinBootstrap5Component],template: ` <touch-spin [(ngModel)]="quantity" [min]="0" [max]="100" [step]="1" ></touch-spin> `})exportclassExampleComponent{quantity=50;}

Reactive forms:

import{Component}from'@angular/core';import{ReactiveFormsModule,FormControl}from'@angular/forms';import{TouchSpinBootstrap5Component}from'@touchspin/angular/bootstrap5'; @Component({selector: 'app-example',standalone: true,imports: [ReactiveFormsModule,TouchSpinBootstrap5Component],template: `<touch-spin [formControl]="amountControl"></touch-spin>`})exportclassExampleComponent{amountControl=newFormControl(50);}

Imperative API:

import{Component,ViewChild}from'@angular/core';import{TouchSpinBootstrap5Component,TouchSpinHandle}from'@touchspin/angular/bootstrap5'; @Component({selector: 'app-example',standalone: true,imports: [TouchSpinBootstrap5Component],template: `<touch-spin #spinner [(ngModel)]="value"></touch-spin>`})exportclassExampleComponent{ @ViewChild('spinner')spinner?: TouchSpinHandle;value=0;increment(){this.spinner?.increment();}}

Per-renderer imports:bootstrap3, bootstrap4, bootstrap5, tailwind, vanillaControlValueAccessor: Full integration with Angular forms SSR-safe: Compatible with Angular Universal

See the @touchspin/angular repository for complete API documentation.

CDN Builds

All CDN-facing entry points are catalogued in docs/cdn-assets.md. Remember that most packages are ESM-only; only the jQuery and Web Component adapters surface UMD globals.

For native ESM in the browser, supply an import map:

<scripttype="importmap">{"imports": {"@touchspin/core": "https://cdn.jsdelivr.net/npm/@touchspin/core@5/dist/index.js","@touchspin/renderer-bootstrap5": "https://cdn.jsdelivr.net/npm/@touchspin/renderer-bootstrap5@5/dist/index.js"}}</script>

Renderer Selection

  • Bootstrap projects: pick the renderer matching your Bootstrap major and include Bootstrap + Popper according to Bootstrap’s own peer dependencies.
  • Headless/vanilla apps: use @touchspin/renderer-vanilla for a lightweight, framework-free theme.
  • Utility-first CSS: @touchspin/renderer-tailwind ships a Tailwind-flavoured stylesheet you can scope or customize.

All renderers attach data-touchspin-injected attributes so the core can wire events without relying on framework-specific selectors.

Release Channels & Dist-Tags

TagIntended audienceNotes
alphapackaging in fluxCurrent default while we stabilize exports and docs.
betafreeze candidateSet once packaging + docs are finalized.
nextrolling canaryUse for CI smoke tests and early adopters.
latestproductionPublished only after graduating from beta.

Publishing is orchestrated through Changesets and the GitHub Actions workflow in .github/workflows/release.yml. See docs/releasing.md for the release playbook, dist-tag promotion policy, and provenance requirements.

Migration from v4

Moving from the legacy [email protected] package? Start with the concise MIGRATION.md and consult deeper architectural notes in docs/architecture/migration-guide.md if you need step-by-step coverage of custom renderers or event differences.

Contributing & Support

  • Start with the workspace overview in AGENTS.md for cross-repo structure and expectations.
  • Read CONTRIBUTING.md for workspace guidelines, required build steps, and Changesets usage.
  • Packaging or security concerns? Follow the disclosure process in SECURITY.md.
  • Dev server, scripts, and architecture references remain in the /docs tree for contributors—see docs/index.md for a full sitemap.

TouchSpin is MIT-licensed. Every published package carries its own LICENSE file generated from the project’s root license.

About

Touch-friendly numeric spinner for React, Tailwind, and vanilla JavaScript

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Sponsor this project

 

Packages

No packages published