UNPKG

bootstrap-touchspin

Version:

A mobile and touch friendly input spinner component for Bootstrap 3, 4 & 5. jQuery plugin with IIFE/UMD builds for backward compatibility.

346 lines (264 loc) 12.5 kB
# TouchSpin v5 > **Formerly Bootstrap TouchSpin** — Now a modern ESM-first monorepo [![Sponsor](https://img.shields.io/badge/Sponsor-GitHub-ea4aaa)](https://github.com/sponsors/istvan-ujjmeszaros) 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](https://github.com/sponsors/istvan-ujjmeszaros)** 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 | Package | Purpose | Primary Entry | Bundled Assets | |---------|---------|---------------|----------------| | `@touchspin/core` | Framework-agnostic logic + renderer contracts | `dist/index.js` (ESM) | Declarations only | | `@touchspin/standalone` | Standalone mount API (core + renderer) | `dist/index.js` (ESM) | Per-renderer subpaths (`dist/bootstrapX.js`) | | `@touchspin/jquery` | Drop-in jQuery wrapper | `dist/index.js` (ESM) | `dist/umd/jquery.touchspin-*.umd.js` globals | | `@touchspin/webcomponent` | `<touchspin-input>` custom element | Per-renderer subpaths | `dist/umd/*.touchspin.umd.js` globals | | `@touchspin/renderer-bootstrap3` | Bootstrap 3 renderer + CSS | `dist/index.js` (ESM) | `dist/touchspin-bootstrap3.css` | | `@touchspin/renderer-bootstrap4` | Bootstrap 4 renderer + CSS | `dist/index.js` (ESM) | `dist/touchspin-bootstrap4.css` | | `@touchspin/renderer-bootstrap5` | Bootstrap 5 renderer + CSS | `dist/index.js` (ESM) | `dist/touchspin-bootstrap5.css` | | `@touchspin/renderer-tailwind` | Tailwind-friendly renderer | `dist/index.js` (ESM) | `dist/touchspin-tailwind.css` | | `@touchspin/renderer-vanilla` | Framework-free renderer + theme | `dist/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: - **[@touchspin/react](https://github.com/istvan-ujjmeszaros/touchspin-react)** (v5.0.1-alpha.0) - Repository: https://github.com/istvan-ujjmeszaros/touchspin-react - Installation: `npm install @touchspin/react@alpha @touchspin/core@alpha` - Per-renderer subpath imports with controlled/uncontrolled patterns - **[@touchspin/angular](https://github.com/istvan-ujjmeszaros/touchspin-angular)** (v5.0.1-alpha.0) - Repository: https://github.com/istvan-ujjmeszaros/touchspin-angular - Installation: `npm install @touchspin/angular@alpha @touchspin/core@alpha` - ControlValueAccessor integration with Angular forms - **[@touchspin/vue](https://github.com/istvan-ujjmeszaros/touchspin-vue)** (v5.1.0) - Repository: https://github.com/istvan-ujjmeszaros/touchspin-vue - Installation: `npm install @touchspin/vue @touchspin/core` - Per-renderer subpath imports with v-model support - **[@touchspin/svelte](https://github.com/istvan-ujjmeszaros/touchspin-svelte)** (v5.0.0) - Repository: https://github.com/istvan-ujjmeszaros/touchspin-svelte - Installation: `npm install @touchspin/svelte @touchspin/core` - Svelte 5 Runes support with bind:value directive 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: ```bash npm install @touchspin/standalone ``` ```ts import { mount } from '@touchspin/standalone/bootstrap5'; const api = mount('#quantity', { min: 0, max: 100, step: 1, cancelable: true // Enable cancelable change events }); // Listen to events const input = document.querySelector('#quantity'); input.addEventListener('change:start', (event) => { // Prevent change if needed if (someCondition) { event.preventDefault(); } }); input.addEventListener('speedchange', (event) => { console.log('Speed changed to:', event.detail.speed); }); ``` **Browser via CDN (ESM)**: ```html <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@touchspin/renderer-bootstrap5@5/dist/touchspin-bootstrap5.css"> <script type="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: ```bash npm install @touchspin/core @touchspin/renderer-bootstrap5 ``` ```ts import { TouchSpin } from '@touchspin/core'; import Bootstrap5Renderer from '@touchspin/renderer-bootstrap5'; import '@touchspin/renderer-bootstrap5/css'; const input = document.querySelector('#quantity'); TouchSpin(input, { renderer: Bootstrap5Renderer, min: 0, max: 100, step: 1, cancelable: true // Enable cancelable change events }); // Listen to events input.addEventListener('change:start', (event) => { // Can prevent the change event.preventDefault(); }); ``` ### jQuery integration ```bash npm install @touchspin/jquery jquery ``` **UMD (Browser)**: ```html <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script> <script src="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**: ```ts import { autoInstall } from '@touchspin/jquery'; import { mount } from '@touchspin/standalone/bootstrap5'; import $ from 'jquery'; autoInstall(mount); $('#quantity').touchspin({ min: 0, max: 100 }); ``` ### Web Component ```bash npm install @touchspin/webcomponent ``` ```ts import '@touchspin/webcomponent/bootstrap5'; ``` ```html <touchspin-input min="0" max="100" value="42"></touchspin-input> ``` ### React ```bash npm install @touchspin/react react react-dom ``` **Controlled:** ```tsx import { useState } from 'react'; import TouchSpin from '@touchspin/react/bootstrap5'; function App() { const [value, setValue] = useState(50); return <TouchSpin value={value} onChange={setValue} min={0} max={100} />; } ``` **Uncontrolled:** ```tsx import TouchSpin from '@touchspin/react/vanilla'; <TouchSpin defaultValue={25} onChange={(val) => console.log(val)} /> ``` **Imperative API:** ```tsx import { useRef } from 'react'; import TouchSpin from '@touchspin/react/tailwind'; import type { TouchSpinHandle } from '@touchspin/react/tailwind'; const ref = useRef<TouchSpinHandle>(null); <TouchSpin ref={ref} defaultValue={10} /> ref.current?.increment(); ``` **Per-renderer imports:** `bootstrap3`, `bootstrap4`, `bootstrap5`, `tailwind`, `vanilla` **SSR-safe:** Works with Next.js, Remix, and other React frameworks **Example app:** [touchspin-react-example](https://github.com/istvan-ujjmeszaros/touchspin-react-example) See the [@touchspin/react repository](https://github.com/istvan-ujjmeszaros/touchspin-react) for complete API documentation. ### Angular ```bash npm install @touchspin/angular @angular/core @angular/common @angular/forms ``` **Template-driven forms:** ```typescript 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> ` }) export class ExampleComponent { quantity = 50; } ``` **Reactive forms:** ```typescript 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>` }) export class ExampleComponent { amountControl = new FormControl(50); } ``` **Imperative API:** ```typescript 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>` }) export class ExampleComponent { @ViewChild('spinner') spinner?: TouchSpinHandle; value = 0; increment() { this.spinner?.increment(); } } ``` **Per-renderer imports:** `bootstrap3`, `bootstrap4`, `bootstrap5`, `tailwind`, `vanilla` **ControlValueAccessor:** Full integration with Angular forms **SSR-safe:** Compatible with Angular Universal See the [@touchspin/angular repository](https://github.com/istvan-ujjmeszaros/touchspin-angular) for complete API documentation. ## CDN Builds All CDN-facing entry points are catalogued in [`docs/cdn-assets.md`](./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: ```html <script type="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 | Tag | Intended audience | Notes | |-----|-------------------|-------| | `alpha` | packaging in flux | Current default while we stabilize exports and docs. | | `beta` | freeze candidate | Set once packaging + docs are finalized. | | `next` | rolling canary | Use for CI smoke tests and early adopters. | | `latest` | production | Published only after graduating from beta. | Publishing is orchestrated through Changesets and the GitHub Actions workflow in `.github/workflows/release.yml`. See [docs/releasing.md](docs/releasing.md) for the release playbook, dist-tag promotion policy, and provenance requirements. ## Migration from v4 Moving from the legacy `bootstrap-touchspin@4.x` package? Start with the concise [MIGRATION.md](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`](AGENTS.md) for cross-repo structure and expectations. - Read [CONTRIBUTING.md](CONTRIBUTING.md) for workspace guidelines, required build steps, and Changesets usage. - Packaging or security concerns? Follow the disclosure process in [SECURITY.md](SECURITY.md). - Dev server, scripts, and architecture references remain in the `/docs` tree for contributors—see [docs/index.md](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.