Skip to content

Commit cad9444

Browse files
committed
fix: Simplify useTimeout logic
1 parent 4fe5836 commit cad9444

File tree

17 files changed

+233
-66
lines changed

17 files changed

+233
-66
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ Vue.use(VueCompositionAPI);
7070
- [`useMouseElement`](./src/components/useMouseElement/stories/useMouseElement.md) — tracks the mouse position relative to given element.
7171
[![Demo](https://img.shields.io/badge/demo-🚀-yellow.svg)](https://microcipcip.github.io/vue-use-kit/?path=/story/sensors-usemouseelement--demo)
7272
- Animations
73+
- [`useIntervalFn`](./src/components/useIntervalFn/stories/useIntervalFn.md) — calls function repeatedly on a fixed time delay.
74+
[![Demo](https://img.shields.io/badge/demo-🚀-yellow.svg)](https://microcipcip.github.io/vue-use-kit/?path=/story/animations-useintervalfn--demo)
7375
- [`useRaf`](./src/components/useRaf/stories/useRaf.md) — returns `elapsedTime` with requestAnimationFrame.
7476
[![Demo](https://img.shields.io/badge/demo-🚀-yellow.svg)](https://microcipcip.github.io/vue-use-kit/?path=/story/animations-useraf--demo)
7577
- [`useRafFn`](./src/components/useRafFn/stories/useRafFn.md) — calls function with requestAnimationFrame.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './useIntervalFn'
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<template>
2+
<table class="table is-fullwidth">
3+
<thead>
4+
<tr>
5+
<th>Prop</th>
6+
<th>Value</th>
7+
</tr>
8+
</thead>
9+
<tbody>
10+
<tr>
11+
<td>callbackCounter</td>
12+
<td>
13+
<span>{{ callbackCounter }}</span>
14+
</td>
15+
</tr>
16+
<tr>
17+
<td colspan="3">
18+
<button class="button is-primary" @click="start" v-if="!isRunning">
19+
Resume Interval
20+
</button>
21+
<button class="button is-danger" @click="stop" v-else>
22+
Stop Interval
23+
</button>
24+
</td>
25+
</tr>
26+
</tbody>
27+
</table>
28+
</template>
29+
30+
<script lang="ts">
31+
import Vue from 'vue'
32+
import { ref } from '@src/api'
33+
import { useIntervalFn } from '@src/vue-use-kit'
34+
35+
export default Vue.extend({
36+
name: 'UseIntervalFnDemo',
37+
setup() {
38+
const ms = 300
39+
const callbackCounter = ref(0)
40+
const animHandler = () => {
41+
callbackCounter.value = callbackCounter.value + 1
42+
}
43+
44+
const { isRunning, start, stop } = useIntervalFn(animHandler, ms)
45+
46+
return { isRunning, start, stop, callbackCounter }
47+
}
48+
})
49+
</script>
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# useIntervalFn
2+
3+
Vue function that calls given callback repeatedly on a fixed time delay.
4+
5+
## Reference
6+
7+
```typescript
8+
useIntervalFn(
9+
callback: Function,
10+
ms?: number,
11+
runOnMount?: boolean
12+
): {
13+
isRunning: Ref<boolean>;
14+
start: () => void;
15+
stop: () => void;
16+
};
17+
```
18+
19+
### Parameters
20+
21+
- `callback: Function` the function to call for each interval finishes
22+
- `ms: number` how many milliseconds to wait before running the callback function
23+
- `runOnMount: boolean` whether to run the interval on mount, `true` by default
24+
25+
### Returns
26+
27+
- `isRunning: Ref<boolean>` this value is `true` if the interval is running, `false` otherwise
28+
- `start: Function` the function used for starting the interval
29+
- `stop: Function` the function used for stopping the interval
30+
31+
## Usage
32+
33+
```html
34+
<template>
35+
<div>
36+
<p>callbackCounter: {{ callbackCounter }}</p>
37+
38+
<button @click="start" v-if="!isRunning">Start Interval</button>
39+
<button @click="stop" v-else>Stop Interval</button>
40+
</div>
41+
</template>
42+
43+
<script lang="ts">
44+
import Vue from 'vue'
45+
import { ref } from '@src/api'
46+
import { useIntervalFn } from 'vue-use-kit'
47+
48+
export default Vue.extend({
49+
name: 'UseIntervalFnDemo',
50+
setup() {
51+
const ms = 300
52+
const callbackCounter = ref(0)
53+
const animHandler = () => {
54+
callbackCounter.value = callbackCounter.value + 1
55+
}
56+
57+
const { isRunning, start, stop } = useIntervalFn(animHandler, ms)
58+
59+
return { isRunning, start, stop, callbackCounter }
60+
}
61+
})
62+
</script>
63+
```
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { storiesOf } from '@storybook/vue'
2+
import path from 'path'
3+
import StoryTitle from '@src/helpers/StoryTitle.vue'
4+
import UseIntervalFnDemo from './UseIntervalFnDemo.vue'
5+
6+
const functionName = 'useIntervalFn'
7+
const functionPath = path.resolve(__dirname, '..')
8+
const notes = require(`./${functionName}.md`).default
9+
10+
const basicDemo = () => ({
11+
components: { StoryTitle, demo: UseIntervalFnDemo },
12+
template: `
13+
<div class="container">
14+
<story-title
15+
function-path="${functionPath}"
16+
source-name="${functionName}"
17+
demo-name="UseIntervalFnDemo.vue"
18+
>
19+
<template v-slot:title></template>
20+
<template v-slot:intro></template>
21+
</story-title>
22+
<demo />
23+
</div>`
24+
})
25+
26+
storiesOf('animations|useIntervalFn', module)
27+
.addParameters({ notes })
28+
.add('Demo', basicDemo)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// import { mount } from '@src/helpers/test'
2+
// import { useIntervalFn } from '@src/vue-use-kit'
3+
4+
describe('useIntervalFn', () => {
5+
it('should do something', () => {
6+
// Add test here
7+
})
8+
})
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { onMounted, onUnmounted, ref } from '@src/api'
2+
3+
export function useIntervalFn(callback: Function, ms = 0, runOnMount = true) {
4+
const isRunning = ref(false)
5+
let interval: any = null
6+
7+
const start = () => {
8+
if (interval) return
9+
isRunning.value = true
10+
interval = setInterval(callback, ms)
11+
}
12+
13+
const stop = () => {
14+
clearInterval(interval)
15+
isRunning.value = false
16+
interval = null
17+
}
18+
19+
onMounted(() => runOnMount && start())
20+
onUnmounted(stop)
21+
22+
return { isRunning, start, stop }
23+
}

src/components/useRaf/stories/UseRafDemo.vue

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,12 @@ import Vue from 'vue'
4242
import { ref, computed } from '@src/api'
4343
import { useRaf } from '@src/vue-use-kit'
4444
45-
const msToTime = (s: number) => {
46-
const pad = (n: number, z = 2) => ('00' + n).slice(-z)
47-
const ms = s % 1000
48-
s = (s - ms) / 1000
49-
const secs = s % 60
50-
s = (s - secs) / 60
51-
const mins = s % 60
52-
const hrs = (s - mins) / 60
53-
return `${pad(hrs)}:${pad(mins)}:${pad(secs)}.${pad(ms, 3)}`
45+
const pad = (n: number) => (n < 10 ? '0' + n : n)
46+
const msToTime = (duration: number) => {
47+
const milliseconds = parseInt(`${(duration % 1000) / 10}`)
48+
const seconds = Math.floor((duration / 1000) % 60)
49+
const minutes = Math.floor((duration / (1000 * 60)) % 60)
50+
return `${pad(minutes)}:${pad(seconds)}.${pad(milliseconds)}`
5451
}
5552
5653
export default Vue.extend({

src/components/useTimeout/stories/UseTimeoutDemo.vue

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
@click="start"
2121
v-text="btnResetMsg"
2222
/>
23-
<button class="button is-danger" @click="cancel">
24-
Cancel Timer
23+
<button class="button is-danger" @click="stop">
24+
Stop Timer
2525
</button>
2626
</td>
2727
</tr>
@@ -38,23 +38,22 @@ export default Vue.extend({
3838
name: 'UseTimeoutDemo',
3939
setup() {
4040
const timerDuration = 3000
41-
const { isReady, isIdle, cancel, start } = useTimeout(
41+
const { isReady, start, stop } = useTimeout(
4242
timerDuration,
4343
false
4444
)
4545
4646
const btnResetMsg = computed(() => {
47-
return isIdle.value ? 'Start timer' : 'Reset Timer'
47+
return isReady.value === null ? 'Start timer' : 'Reset Timer'
4848
})
4949
5050
const timerStatus = computed(() => {
51-
if (isIdle.value) return 'Idle'
5251
if (isReady.value === false) return 'Pending...'
53-
if (isReady.value === null) return 'Cancelled'
52+
if (isReady.value === null) return 'Idle'
5453
return 'Completed'
5554
})
5655
57-
return { btnResetMsg, timerStatus, cancel, start }
56+
return { btnResetMsg, timerStatus, start, stop }
5857
}
5958
})
6059
</script>

src/components/useTimeout/stories/useTimeout.md

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,8 @@ useTimeout(
1010
runOnMount?: boolean
1111
): {
1212
isReady: Ref<boolean | null>;
13-
isIdle: Ref<boolean>;
14-
cancel: () => void;
1513
start: () => void;
14+
stop: () => void;
1615
}
1716
```
1817

@@ -26,10 +25,9 @@ useTimeout(
2625
- `isReady: Ref<boolean | null>` the timer status
2726
- `false` when the timer is executing
2827
- `true` when the timer is completed
29-
- `null` when the timer is cancelled
30-
- `isIdle: Ref<boolean>` this value is `true` if the timer has ever been called, `false` otherwise
31-
- `cancel: Function` the function used to cancel the timer
28+
- `null` when the timer is idle
3229
- `start: Function` the function used for starting or resetting the timer
30+
- `stop: Function` the function used to stop the timer
3331

3432
## Usage
3533

@@ -39,7 +37,7 @@ useTimeout(
3937
<p>Timer status: {{ isReady ? 'Called!' : 'Pending...' }}</p>
4038

4139
<button @click="start">Reset Timer</button>
42-
<button @click="cancel">Cancel Timer</button>
40+
<button @click="stop">Stop Timer</button>
4341
</div>
4442
</template>
4543

@@ -51,8 +49,8 @@ useTimeout(
5149
name: 'UseTimeoutDemo',
5250
setup() {
5351
const timerDuration = 3000
54-
const { isReady, cancel, start } = useTimeout(timerDuration)
55-
return { isReady, cancel, start }
52+
const { isReady, start, stop } = useTimeout(timerDuration)
53+
return { isReady, start, stop }
5654
}
5755
})
5856
</script>

0 commit comments

Comments
 (0)