1- import { isTouchDevice } from 'helpers/functions'
1+ import { isTouchDevice , debounce } from 'helpers/functions'
22
33const formatters = {
44 opacity : v => ( v * 10 ) + '%' ,
@@ -28,11 +28,31 @@ export function initSteppers () {
2828 const decBtn = stepper . querySelector ( '.stepper-btn-dec' )
2929 const incBtn = stepper . querySelector ( '.stepper-btn-inc' )
3030
31- decBtn . addEventListener ( 'click' , ( ) => adjustValue ( input , - step , stepper ) )
32- incBtn . addEventListener ( 'click' , ( ) => adjustValue ( input , step , stepper ) )
31+ initRepeatButton ( decBtn , ( ) => adjustValue ( input , - step , stepper ) )
32+ initRepeatButton ( incBtn , ( ) => adjustValue ( input , step , stepper ) )
3333 } )
3434}
3535
36+ function initRepeatButton ( button , action ) {
37+ let timer
38+ const stop = ( ) => clearTimeout ( timer )
39+ const repeat = ( delay ) => {
40+ action ( )
41+ timer = setTimeout ( ( ) => repeat ( 80 ) , delay )
42+ }
43+ button . addEventListener ( 'pointerdown' , ( event ) => {
44+ if ( event . button !== 0 ) return
45+ button . setPointerCapture ( event . pointerId )
46+ repeat ( 400 )
47+ } )
48+ button . addEventListener ( 'pointerup' , stop )
49+ button . addEventListener ( 'pointercancel' , stop )
50+ button . addEventListener ( 'lostpointercapture' , stop )
51+ // pointerdown already handled mouse and touch, only keyboard activation (detail 0) is left
52+ button . addEventListener ( 'click' , ( event ) => { if ( event . detail === 0 ) action ( ) } )
53+ button . addEventListener ( 'contextmenu' , ( event ) => event . preventDefault ( ) )
54+ }
55+
3656function adjustValue ( input , delta , stepper ) {
3757 const min = Number ( input . min )
3858 const max = Number ( input . max )
@@ -43,7 +63,8 @@ function adjustValue (input, delta, stepper) {
4363 input . value = newValue
4464 stepper . querySelector ( '.stepper-val' ) . textContent = formatValue ( input . id , newValue )
4565 input . dispatchEvent ( new Event ( 'input' , { bubbles : true } ) )
46- input . dispatchEvent ( new Event ( 'change' , { bubbles : true } ) )
66+ // change handlers save to the server, so send only the final value of a click series
67+ debounce ( ( ) => input . dispatchEvent ( new Event ( 'change' , { bubbles : true } ) ) , 'stepper-' + input . id , 500 )
4768}
4869
4970export function syncStepperValues ( ) {
0 commit comments