-
-
Notifications
You must be signed in to change notification settings - Fork 3.8k
/
Copy pathStepHandler.tsx
104 lines (91 loc) · 2.9 KB
/
StepHandler.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import isMobile from '../../vc-util/isMobile';
import { onBeforeUnmount, ref, defineComponent } from 'vue';
import classNames from '../../_util/classNames';
import { functionType } from '../../_util/type';
/**
* When click and hold on a button - the speed of auto changing the value.
*/
const STEP_INTERVAL = 200;
/**
* When click and hold on a button - the delay before auto changing the value.
*/
const STEP_DELAY = 600;
export default defineComponent({
compatConfig: { MODE: 3 },
name: 'StepHandler',
inheritAttrs: false,
props: {
prefixCls: String,
upDisabled: Boolean,
downDisabled: Boolean,
onStep: functionType<(up: boolean) => void>(),
},
slots: ['upNode', 'downNode'],
setup(props, { slots, emit }) {
const stepTimeoutRef = ref();
// We will interval update step when hold mouse down
const onStepMouseDown = (e: MouseEvent, up: boolean) => {
e.preventDefault();
emit('step', up);
// Loop step for interval
function loopStep() {
emit('step', up);
stepTimeoutRef.value = setTimeout(loopStep, STEP_INTERVAL);
}
// First time press will wait some time to trigger loop step update
stepTimeoutRef.value = setTimeout(loopStep, STEP_DELAY);
};
const onStopStep = () => {
clearTimeout(stepTimeoutRef.value);
};
onBeforeUnmount(() => {
onStopStep();
});
return () => {
if (isMobile()) {
return null;
}
const { prefixCls, upDisabled, downDisabled } = props;
const handlerClassName = `${prefixCls}-handler`;
const upClassName = classNames(handlerClassName, `${handlerClassName}-up`, {
[`${handlerClassName}-up-disabled`]: upDisabled,
});
const downClassName = classNames(handlerClassName, `${handlerClassName}-down`, {
[`${handlerClassName}-down-disabled`]: downDisabled,
});
const sharedHandlerProps = {
unselectable: 'on' as const,
role: 'button',
onMouseup: onStopStep,
onMouseleave: onStopStep,
};
const { upNode, downNode } = slots;
return (
<div class={`${handlerClassName}-wrap`}>
<span
{...sharedHandlerProps}
onMousedown={e => {
onStepMouseDown(e, true);
}}
aria-label="Increase Value"
aria-disabled={upDisabled}
class={upClassName}
>
{upNode?.() || <span unselectable="on" class={`${prefixCls}-handler-up-inner`} />}
</span>
<span
{...sharedHandlerProps}
onMousedown={e => {
onStepMouseDown(e, false);
}}
aria-label="Decrease Value"
aria-disabled={downDisabled}
class={downClassName}
>
{downNode?.() || <span unselectable="on" class={`${prefixCls}-handler-down-inner`} />}
</span>
</div>
);
};
},
});