Skip to content

Commit cb6f36f

Browse files
committed
Initial commit
1 parent 6aca1a5 commit cb6f36f

13 files changed

+379
-0
lines changed

.editorconfig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# EditorConfig is awesome: https://EditorConfig.org
2+
3+
# top-most EditorConfig file
4+
root = true
5+
6+
[*]
7+
indent_style = tab
8+
indent_size = 2
9+
end_of_line = lf
10+
charset = utf-8
11+
trim_trailing_whitespace = true
12+
insert_final_newline = true

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules
2+
pnpm-lock.yaml

.prettierrc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"trailingComma": "es5",
3+
"semi": false,
4+
"singleQuote": true,
5+
"useTabs": true,
6+
"quoteProps": "consistent",
7+
"bracketSpacing": true,
8+
"arrowParens": "always",
9+
"printWidth": 200
10+
}

README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# input-touchspin
2+
3+
Javascript touch friendly input spinner
4+
5+
## Features
6+
7+
- Pure javascript (no jQuery)
8+
- CSS Framework Agnostic
9+
- Using native HTMLInputElement.stepUp() and HTMLInputElement.stepDown() methods
10+
- Lightweight (< 70 LOC)
11+
12+
## Installation
13+
14+
Install with npm:
15+
16+
```bash
17+
npm install @erwinstone/input-touchspin
18+
```
19+
20+
Install from cdn:
21+
22+
```html
23+
<script src="https://unpkg.com/@erwinstone/[email protected]/dist/input-touchspin.min.js"></script>
24+
```
25+
26+
##
27+
28+
Demos and documentation: https://input-touchspin.vercel.app/

dist/input-touchspin.d.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
declare class InputTouchspin {
2+
private input;
3+
private btnUp;
4+
private btnDown;
5+
private styleId;
6+
private timeout;
7+
private interval;
8+
constructor(target: Element);
9+
private style;
10+
private events;
11+
private clearTimers;
12+
private step;
13+
private spin;
14+
}
15+
export default InputTouchspin;

dist/input-touchspin.js

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*!
2+
* @erwinstone/input-touchspin v1.0.0 (https://input-touchspin.vercel.app/)
3+
* Copyright 2021 erwinstone
4+
* Licensed under MIT (https://github.com/erwinstone/input-touchspin/blob/master/LICENSE)
5+
*/
6+
(function (global, factory) {
7+
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
8+
typeof define === 'function' && define.amd ? define(factory) :
9+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.BsToast = factory());
10+
})(this, (function () { 'use strict';
11+
12+
class InputTouchspin {
13+
constructor(target) {
14+
this.styleId = "input-touchspin-style";
15+
this.input = target.querySelector("[data-touchspin-input]");
16+
this.btnUp = target.querySelector("[data-touchspin-up]");
17+
this.btnDown = target.querySelector("[data-touchspin-down]");
18+
this.style();
19+
if (!this.input.readOnly && !this.input.disabled) {
20+
this.events();
21+
}
22+
}
23+
style() {
24+
if (document.getElementById(this.styleId) === null) {
25+
const style = document.createElement("style");
26+
style.id = this.styleId;
27+
style.textContent = "[data-touchspin-input]::-webkit-inner-spin-button,[data-touchspin-input]::-webkit-outer-spin-button{margin:0;-webkit-appearance:none}[data-touchspin-input]{-moz-appearance:textfield}";
28+
document.head.appendChild(style);
29+
}
30+
}
31+
events() {
32+
this.btnUp.addEventListener("mousedown", () => this.spin());
33+
this.btnDown.addEventListener("mousedown", () => this.spin(false));
34+
this.btnUp.addEventListener("touchstart", (e) => {
35+
this.spin();
36+
e.cancelable && e.preventDefault();
37+
});
38+
this.btnDown.addEventListener("touchstart", (e) => {
39+
this.spin(false);
40+
e.cancelable && e.preventDefault();
41+
});
42+
Array.from(["mouseup", "mouseleave", "touchend"]).forEach((e) => {
43+
this.btnUp.addEventListener(e, () => this.clearTimers());
44+
this.btnDown.addEventListener(e, () => this.clearTimers());
45+
});
46+
this.input.addEventListener("wheel", (e) => {
47+
Math.sign(e.deltaY) < 1 ? this.step() : this.step(false);
48+
e.preventDefault();
49+
});
50+
}
51+
clearTimers() {
52+
clearTimeout(this.timeout);
53+
clearInterval(this.interval);
54+
}
55+
step(up = true) {
56+
const before = this.input.value;
57+
up ? this.input.stepUp() : this.input.stepDown();
58+
const after = this.input.value;
59+
before !== after && this.input.dispatchEvent(new Event("change"));
60+
}
61+
spin(up = true) {
62+
this.step(up);
63+
this.timeout = setTimeout(() => this.interval = setInterval(() => this.step(up), 50), 300);
64+
}
65+
}
66+
67+
return InputTouchspin;
68+
69+
}));

dist/input-touchspin.min.js

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/input-touchspin.module.d.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
declare class InputTouchspin {
2+
private input;
3+
private btnUp;
4+
private btnDown;
5+
private styleId;
6+
private timeout;
7+
private interval;
8+
constructor(target: Element);
9+
private style;
10+
private events;
11+
private clearTimers;
12+
private step;
13+
private spin;
14+
}
15+
export default InputTouchspin;

dist/input-touchspin.module.js

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*!
2+
* @erwinstone/input-touchspin v1.0.0 (https://input-touchspin.vercel.app/)
3+
* Copyright 2021 erwinstone
4+
* Licensed under MIT (https://github.com/erwinstone/input-touchspin/blob/master/LICENSE)
5+
*/
6+
class InputTouchspin {
7+
constructor(target) {
8+
this.styleId = "input-touchspin-style";
9+
this.input = target.querySelector("[data-touchspin-input]");
10+
this.btnUp = target.querySelector("[data-touchspin-up]");
11+
this.btnDown = target.querySelector("[data-touchspin-down]");
12+
this.style();
13+
if (!this.input.readOnly && !this.input.disabled) {
14+
this.events();
15+
}
16+
}
17+
style() {
18+
if (document.getElementById(this.styleId) === null) {
19+
const style = document.createElement("style");
20+
style.id = this.styleId;
21+
style.textContent = "[data-touchspin-input]::-webkit-inner-spin-button,[data-touchspin-input]::-webkit-outer-spin-button{margin:0;-webkit-appearance:none}[data-touchspin-input]{-moz-appearance:textfield}";
22+
document.head.appendChild(style);
23+
}
24+
}
25+
events() {
26+
this.btnUp.addEventListener("mousedown", () => this.spin());
27+
this.btnDown.addEventListener("mousedown", () => this.spin(false));
28+
this.btnUp.addEventListener("touchstart", (e) => {
29+
this.spin();
30+
e.cancelable && e.preventDefault();
31+
});
32+
this.btnDown.addEventListener("touchstart", (e) => {
33+
this.spin(false);
34+
e.cancelable && e.preventDefault();
35+
});
36+
Array.from(["mouseup", "mouseleave", "touchend"]).forEach((e) => {
37+
this.btnUp.addEventListener(e, () => this.clearTimers());
38+
this.btnDown.addEventListener(e, () => this.clearTimers());
39+
});
40+
this.input.addEventListener("wheel", (e) => {
41+
Math.sign(e.deltaY) < 1 ? this.step() : this.step(false);
42+
e.preventDefault();
43+
});
44+
}
45+
clearTimers() {
46+
clearTimeout(this.timeout);
47+
clearInterval(this.interval);
48+
}
49+
step(up = true) {
50+
const before = this.input.value;
51+
up ? this.input.stepUp() : this.input.stepDown();
52+
const after = this.input.value;
53+
before !== after && this.input.dispatchEvent(new Event("change"));
54+
}
55+
spin(up = true) {
56+
this.step(up);
57+
this.timeout = setTimeout(() => this.interval = setInterval(() => this.step(up), 50), 300);
58+
}
59+
}
60+
61+
export { InputTouchspin as default };

dist/input-touchspin.module.min.js

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)