Skip to content

Commit 654a396

Browse files
committed
Fixed a bug where onHoldEnd must be fired right before onRelease
1 parent bc583c2 commit 654a396

2 files changed

Lines changed: 39 additions & 20 deletions

File tree

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,21 @@ npm install --save react-repeatable
4343

4444
## API
4545

46+
### Sequence of Events
47+
48+
#### Hold action is occurred
49+
onPress -> onHoldStart -> onHold (once or more) -> onHoldEnd -> onRelease
50+
51+
#### Hold action is not occurred
52+
onPress -> onRelease
53+
4654
### Properties
4755

4856
Name | Type | Default | Description
4957
:--- | :--- | :------ | :----------
5058
repeatDelay | Number | 500 | The time (in milliseconds) to wait before the first hold action is being triggered.
5159
repeatInterval | Number | 32 | The time interval (in milliseconds) on how often to trigger a hold action.
52-
repeatCount | Number | | The number of times the hold action will take place.
60+
repeatCount | Number | 0 | The number of times the hold action will take place. A zero value will disable the repeat counter.
5361
onPress | Function(event) | | Callback fired when the mousedown or touchstart event is triggered.
5462
onHoldStart | Function() | | Callback fired once before the first hold action.
5563
onHold | Function() | | Callback fired mutiple times while holding down.

src/Repeatable.jsx

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class Repeatable extends PureComponent {
1515
PropTypes.string
1616
]),
1717

18-
// The number of times the hold action will take place.
18+
// The number of times the hold action will take place. A zero value will disable the repeat counter.
1919
repeatCount: PropTypes.oneOfType([
2020
PropTypes.number,
2121
PropTypes.string
@@ -38,36 +38,45 @@ class Repeatable extends PureComponent {
3838
};
3939
static defaultProps = {
4040
repeatDelay: 500,
41-
repeatInterval: 32
41+
repeatInterval: 32,
42+
repeatCount: 0
4243
};
4344

4445
repeatDelayTimer = null;
4546
repeatIntervalTimer = null;
47+
repeatAmount = 0;
4648

4749
acquireTimer = () => {
4850
const repeatDelay = Math.max(Number(this.props.repeatDelay) || 0, 0);
4951
const repeatInterval = Math.max(Number(this.props.repeatInterval) || 0, 0);
5052
const repeatCount = Math.max(Number(this.props.repeatCount) || 0, 0);
5153

54+
this.repeatAmount = 0;
5255
this.releaseTimer();
5356

54-
let repeatAmount = 0;
5557
this.repeatDelayTimer = setTimeout(() => {
58+
if ((repeatCount > 0) && (this.repeatAmount >= repeatCount)) {
59+
return;
60+
}
61+
62+
this.repeatAmount++;
63+
5664
if (typeof this.props.onHoldStart === 'function') {
5765
this.props.onHoldStart();
5866
}
5967
if (typeof this.props.onHold === 'function') {
60-
if (!repeatCount || (repeatAmount < repeatCount)) {
61-
++repeatAmount;
62-
this.props.onHold();
63-
}
68+
this.props.onHold();
6469
}
70+
6571
this.repeatIntervalTimer = setInterval(() => {
66-
if (this.repeatIntervalTimer && (typeof this.props.onHold === 'function')) {
67-
if (!repeatCount || (repeatAmount < repeatCount)) {
68-
++repeatAmount;
69-
this.props.onHold();
70-
}
72+
if ((repeatCount > 0) && (this.repeatAmount >= repeatCount)) {
73+
return;
74+
}
75+
76+
this.repeatAmount++;
77+
78+
if (typeof this.props.onHold === 'function') {
79+
this.props.onHold();
7180
}
7281
}, repeatInterval);
7382
}, repeatDelay);
@@ -85,6 +94,7 @@ class Repeatable extends PureComponent {
8594
};
8695

8796
componentWillUnmount() {
97+
this.repeatAmount = 0;
8898
this.releaseTimer();
8999
}
90100
render() {
@@ -101,17 +111,18 @@ class Repeatable extends PureComponent {
101111
} = this.props;
102112

103113
const release = (event) => {
104-
if (typeof this.props.onRelease === 'function') {
105-
this.props.onRelease(event);
114+
if (this.repeatAmount > 0) {
115+
if (typeof this.props.onHoldEnd === 'function') {
116+
this.props.onHoldEnd();
117+
}
106118
}
107119

120+
this.repeatAmount = 0;
108121
this.releaseTimer();
109122

110-
setTimeout(() => {
111-
if (typeof this.props.onHoldEnd === 'function') {
112-
this.props.onHoldEnd();
113-
}
114-
}, 0);
123+
if (typeof this.props.onRelease === 'function') {
124+
this.props.onRelease(event);
125+
}
115126
};
116127

117128
const press = (event) => {

0 commit comments

Comments
 (0)