bootstrap-input-spinner 5.0.4 → 5.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -124,6 +124,7 @@ const props = {
124
124
  autoInterval: 50, // speed of auto value change, set to `undefined` to disable auto-change
125
125
  buttonsOnly: false, // set this `true` to disable the possibility to enter or paste the number via keyboard
126
126
  keyboardStepping: true, // set this to `false` to disallow the use of the up and down arrow keys to step
127
+ mouseWheel: false, // set to `true` to step the value on mouse wheel when the input is focused
127
128
  locale: navigator.language, // the locale, per default detected automatically from the browser
128
129
  editor: I18nEditor, // the editor (parsing and rendering of the input)
129
130
  template: // the template of the input
@@ -175,6 +176,12 @@ the plus and minus buttons still allow to change the value.
175
176
  In `keyboardStepping` mode (set `true`) allows the use of the up/down arrow keys to increase/decrease the number by the
176
177
  step.
177
178
 
179
+ ##### mouseWheel
180
+
181
+ Off by default, matching modern browsers which no longer wheel-step native `<input type="number">` elements. Set to
182
+ `true` to enable mouse-wheel stepping. The wheel listener is only attached while the input has focus, so an unfocused
183
+ spinner never hijacks page scroll. Scroll up increases the value, scroll down decreases it.
184
+
178
185
  ##### locale
179
186
 
180
187
  Used to format the number in the UI. Detected automatically from the user's browser, can be set to "de", "en",… or "
package/index.html CHANGED
@@ -212,6 +212,22 @@ inputGross.addEventListener("input", function (event) {
212
212
  </script>
213
213
  <pre><code class="language-js">new InputSpinner(element, {buttonsOnly: true, autoInterval: undefined})</code></pre>
214
214
 
215
+ <h3>Mouse wheel stepping</h3>
216
+ <p>
217
+ Off by default, matching what modern browsers do with the native <code>&lt;input type="number"&gt;</code>.
218
+ Pass <code>mouseWheel: true</code> to enable it. The listener is attached only while the input has focus,
219
+ so an unfocused spinner never hijacks page scroll.
220
+ </p>
221
+ <p>
222
+ <label for="inputMouseWheel">Focus and scroll to step</label>
223
+ <input id="inputMouseWheel" type="number" value="50" min="0" max="100" step="1"/>
224
+ </p>
225
+ <script type="module">
226
+ import {InputSpinner} from "./src/InputSpinner.js"
227
+ new InputSpinner(document.getElementById("inputMouseWheel"), {mouseWheel: true})
228
+ </script>
229
+ <pre><code class="language-js">new InputSpinner(element, {mouseWheel: true})</code></pre>
230
+
215
231
  <h3>Dynamically handling of the <code>class</code> attribute</h3>
216
232
  <p>
217
233
  <input id="inputChangeClass" class="is-valid" type="number" value="50"/>
@@ -471,6 +487,7 @@ new InputSpinner(document.getElementById("timeEditor"), {editor: TimeEditor})</c
471
487
  import {InputSpinner} from "./src/InputSpinner.js"
472
488
 
473
489
  for (const el of document.querySelectorAll("input[type='number']")) {
490
+ if (el["bootstrap-input-spinner"]) continue
474
491
  new InputSpinner(el)
475
492
  }
476
493
  </script>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bootstrap-input-spinner",
3
- "version": "5.0.4",
3
+ "version": "5.0.5",
4
4
  "description": "A Bootstrap 5 plugin to create input spinner elements for number input.",
5
5
  "browser": "./src/InputSpinner.js",
6
6
  "type": "module",
@@ -65,6 +65,7 @@ export class InputSpinner {
65
65
  autoInterval: 50, // speed of auto value change, set to `undefined` to disable auto-change
66
66
  buttonsOnly: false, // set this `true` to disable the possibility to enter or paste the number via keyboard
67
67
  keyboardStepping: true, // set this to `false` to disallow the use of the up and down arrow keys to step
68
+ mouseWheel: false, // set `true` to step the value on wheel when the input is focused. Off by default — modern browsers no longer wheel-step native <input type="number">.
68
69
  locale: navigator.language, // the locale, per default detected automatically from the browser
69
70
  editor: I18nEditor, // the editor (parsing and rendering of the input)
70
71
  template: // the template of the input
@@ -202,6 +203,35 @@ export class InputSpinner {
202
203
  }
203
204
  })
204
205
 
206
+ // Focus-gated mouse-wheel stepping: matches native <input type="number">.
207
+ // The listener is attached on focus and detached on blur, so an
208
+ // unfocused spinner never hijacks page scroll and no passive-listener
209
+ // warnings are produced while the input is idle.
210
+ const onWheel = function (event) {
211
+ if (self.input.disabled || self.input.readOnly) return
212
+ if (event.deltaY === 0) return
213
+ event.preventDefault()
214
+ // Scroll up → increment (macOS natural-scroll convention:
215
+ // pushing the wheel/trackpad up yields deltaY > 0).
216
+ const direction = event.deltaY > 0 ? 1 : -1
217
+ calcStep(direction * self.step)
218
+ dispatchEvent(self.original, "change")
219
+ }
220
+ let wheelBound = false
221
+ const attachWheel = function () {
222
+ if (wheelBound || !self.props.mouseWheel) return
223
+ self.input.addEventListener("wheel", onWheel, {passive: false})
224
+ wheelBound = true
225
+ }
226
+ const detachWheel = function () {
227
+ if (!wheelBound) return
228
+ self.input.removeEventListener("wheel", onWheel, {passive: false})
229
+ wheelBound = false
230
+ }
231
+ bind(this.input, "focus", attachWheel)
232
+ bind(this.input, "blur", detachWheel)
233
+ self._teardown.push(detachWheel)
234
+
205
235
  // decrement button
206
236
  onPointerDown(self.buttonDecrement, function () {
207
237
  if (!self.buttonDecrement.disabled) {
@@ -214,6 +214,56 @@ describe("InputSpinner dynamic step while holding", () => {
214
214
  })
215
215
  })
216
216
 
217
+ describe("InputSpinner mouse wheel", () => {
218
+ function wheel(input, deltaY) {
219
+ input.dispatchEvent(new WheelEvent("wheel", {deltaY, cancelable: true, bubbles: true}))
220
+ }
221
+ it("is disabled by default (matches modern native behavior)", () => {
222
+ const {el, group} = spin({value: "5", min: "0", max: "10", step: "1"})
223
+ const visible = group.querySelector("input")
224
+ visible.focus()
225
+ wheel(visible, 100)
226
+ wheel(visible, -100)
227
+ assert.equal(el.value, "5")
228
+ clear()
229
+ })
230
+ it("scroll up (positive deltaY) increments when enabled and focused (#132)", () => {
231
+ const {el, group} = spin({value: "5", min: "0", max: "10", step: "1"}, {mouseWheel: true})
232
+ const visible = group.querySelector("input")
233
+ visible.focus()
234
+ wheel(visible, 100)
235
+ assert.equal(el.value, "6")
236
+ clear()
237
+ })
238
+ it("scroll down (negative deltaY) decrements when enabled and focused", () => {
239
+ const {el, group} = spin({value: "5", min: "0", max: "10", step: "1"}, {mouseWheel: true})
240
+ const visible = group.querySelector("input")
241
+ visible.focus()
242
+ wheel(visible, -100)
243
+ assert.equal(el.value, "4")
244
+ clear()
245
+ })
246
+ it("does not step when the input is not focused (#115)", () => {
247
+ const {el, group} = spin({value: "5", min: "0", max: "10", step: "1"}, {mouseWheel: true})
248
+ const visible = group.querySelector("input")
249
+ // never focus
250
+ wheel(visible, 100)
251
+ assert.equal(el.value, "5")
252
+ clear()
253
+ })
254
+ it("stops stepping after the input blurs", () => {
255
+ const {el, group} = spin({value: "5", min: "0", max: "10", step: "1"}, {mouseWheel: true})
256
+ const visible = group.querySelector("input")
257
+ visible.focus()
258
+ wheel(visible, 100)
259
+ assert.equal(el.value, "6")
260
+ visible.blur()
261
+ wheel(visible, 100)
262
+ assert.equal(el.value, "6")
263
+ clear()
264
+ })
265
+ })
266
+
217
267
  describe("InputSpinner events", () => {
218
268
  it("dispatches 'input' when stepping", async () => {
219
269
  const {el, group} = spin({value: "5", min: "0", max: "10"})