Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/10 add usetimeout and useinterval hooks #16

Open
wants to merge 33 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
32a9035
Add the useTimeout hook
larsvanbraam Apr 22, 2022
8487c27
Update the useTimeout hook to return more explicit methods
larsvanbraam Apr 22, 2022
90ff012
Add the useInterval hook
larsvanbraam Apr 26, 2022
d6b2e6a
Merge branch 'main' into feature/10-add-usetimeout-and-useinterval-hooks
larsvanbraam Apr 26, 2022
2659a29
Implement the storybook log on the useTimeout hook
larsvanbraam Apr 26, 2022
a424f75
Remove the excessive space
larsvanbraam Apr 26, 2022
5f65389
Update the timeout stories
larsvanbraam Apr 26, 2022
c9adccd
Update the useInterval stories and tests
larsvanbraam Apr 26, 2022
65f03be
Merge branch 'main' into feature/10-add-usetimeout-and-useinterval-hooks
larsvanbraam Apr 26, 2022
baadfb6
Choose set in favour of create because it matches the native name
larsvanbraam Apr 29, 2022
dcaabc6
Merge branch 'main' into feature/10-add-usetimeout-and-useinterval-hooks
larsvanbraam Apr 29, 2022
ec95546
Update the muban peer dependency version
larsvanbraam Apr 29, 2022
a0fc164
Expose the state of the interval
larsvanbraam Apr 29, 2022
6189557
Remove the unused ref import
larsvanbraam Apr 29, 2022
1a4e173
Move the ref import to the main one
larsvanbraam Apr 29, 2022
d9c3bed
Implement the userEvent on the userIntervalStories.test
larsvanbraam Apr 29, 2022
55bd78e
Implement the userEvent on the useTimeoutStories.test
larsvanbraam Apr 29, 2022
28aa255
Implement jest.useFakeTimers on the main tests
larsvanbraam Apr 29, 2022
a48a9a6
Rename the handle variable to intervalId
larsvanbraam Apr 29, 2022
d4a7889
Rename the handle variable to timeoutId
larsvanbraam Apr 29, 2022
c56236b
Increase the time to ensure stop actually works
larsvanbraam Apr 29, 2022
96276ce
Remove the story that tests the stop button
larsvanbraam Apr 29, 2022
6778653
Move up the callback methods
larsvanbraam Apr 29, 2022
6a55551
Update the test description
larsvanbraam Apr 29, 2022
078f18b
Fix prettier formatting
larsvanbraam Apr 29, 2022
0174fe2
Switch to a Readonly Ref instead of a ComputedRef
larsvanbraam Apr 29, 2022
8d8de00
Use the intervalId to keep track if the interval is running.
larsvanbraam Apr 29, 2022
4f85184
Implement the isTimeoutRunning state in the useTimeout hook to stay c…
larsvanbraam Apr 29, 2022
483fc83
Update the docs to include the new isTimeoutRunning
larsvanbraam Apr 29, 2022
70a6a7c
Add a test to check if the isTimeoutRunning is correctly set
larsvanbraam Apr 29, 2022
13e6fb5
Include the isIntervalRunning type to the useInterval docs
larsvanbraam Apr 29, 2022
e8df249
Remove the usage of the actual timeout in the tests
larsvanbraam Apr 29, 2022
979e56e
rename cancelTimeout to clearTimeout to be more consistent with the n…
larsvanbraam Apr 29, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"plop": "plop"
},
"peerDependencies": {
"@muban/muban": "^1.0.0-alpha.28"
"@muban/muban": "^1.0.0-alpha.34"
},
"devDependencies": {
"@babel/core": "^7.12.10",
Expand Down
9 changes: 5 additions & 4 deletions src/useInterval/useInterval.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Meta } from '@storybook/addon-docs';

# useInterval

The `useInterval` hook is a wrapper around the native `setInterval`, it allows you to easily create set
The `useInterval` hook is a wrapper around the native `setInterval`, it allows you to easily set
an interval within your component that will be auto cancelled when the component unmounts.
larsvanbraam marked this conversation as resolved.
Show resolved Hide resolved

## Reference
Expand All @@ -25,14 +25,15 @@ function useInterval(
* `startImmediate` - Whether or not you want to immediately start the interval.

### Returns
* `{ startInterval, stopInterval }`
* `{ startInterval, stopInterval, isIntervalRunning }`
* `startInterval` – A function that starts the interval, any running intervals will automatically be stopped.
* `stopInterval` – A function that will stop the current active interval.
* `isIntervalRunning` – A computed ref that keeps track whether or not the interval is running.

## Usage

```ts
const { startInterval, stopInterval } = useInterval(() => {
const { startInterval, stopInterval, isIntervalRunning } = useInterval(() => {
console.log('The interval has run')
}, 1000, false);
````
Expand All @@ -51,7 +52,7 @@ const Demo = defineComponent({
}, 1000);

// The interval doesn't start automatically, but requires a user action to start.
const { startInterval, stopInterval } = useInterval(() => {
const { startInterval, stopInterval, isIntervalRunning } = useInterval(() => {
console.log('The user-action interval callback is triggered.')
}, 1000, false);

Expand Down
5 changes: 1 addition & 4 deletions src/useInterval/useInterval.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,8 @@ export const Demo: Story<DemoStoryProps> = () => ({
},
setup({ refs, props }) {
const [logBinding, log] = useStorybookLog(refs.label);
const isIntervalRunning = ref(false);

const { startInterval, stopInterval } = useInterval(
const { startInterval, stopInterval, isIntervalRunning } = useInterval(
onInterval,
props.interval,
props.startImmediate,
Expand All @@ -44,7 +43,6 @@ export const Demo: Story<DemoStoryProps> = () => ({
disabled: isIntervalRunning,
},
click() {
isIntervalRunning.value = true;
startInterval();
},
}),
Expand All @@ -53,7 +51,6 @@ export const Demo: Story<DemoStoryProps> = () => ({
disabled: computed(() => !isIntervalRunning.value),
},
click() {
isIntervalRunning.value = false;
log('interval stopped');
stopInterval();
},
Expand Down
19 changes: 16 additions & 3 deletions src/useInterval/useInterval.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,26 @@ describe('useInterval', () => {
expect(mockHandler).toBeCalledTimes(0);
});

it('should start a new interval before the old one was triggered and only complete once', async () => {
it('should know that the interval is running', async () => {
const mockHandler = jest.fn();

await runComponentSetup(
() => {
return useInterval(mockHandler, 100, false);
() => useInterval(mockHandler, 200, false),
async ({ startInterval, stopInterval, isIntervalRunning }) => {
startInterval();
await timeout(100);
expect(isIntervalRunning.value).toEqual(true);
stopInterval();
expect(isIntervalRunning.value).toEqual(false);
},
);
});

it('should start a new interval before the old one was triggered and only complete once', async () => {
const mockHandler = jest.fn();

await runComponentSetup(
() => useInterval(mockHandler, 100, false),
async ({ startInterval }) => {
startInterval();
await timeout(50);
Expand Down
19 changes: 16 additions & 3 deletions src/useInterval/useInterval.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { onMounted, onUnmounted } from '@muban/muban';
import type { ComputedRef } from '@muban/muban';
import { computed, onMounted, onUnmounted } from '@muban/muban';
import { ref } from '@muban/muban/dist/esm';

/**
* A hook that can be used to call a function on a provided interval, by default the interval
Expand All @@ -12,15 +14,22 @@ export const useInterval = (
callback: () => void,
interval: number = 100,
startImmediate: boolean = true,
): { startInterval: () => void; stopInterval: () => void } => {
): {
startInterval: () => void;
stopInterval: () => void;
isIntervalRunning: ComputedRef<boolean>;
} => {
const isIntervalRunning = ref(false);
larsvanbraam marked this conversation as resolved.
Show resolved Hide resolved
let handle = -1;
larsvanbraam marked this conversation as resolved.
Show resolved Hide resolved

function start() {
stop();
isIntervalRunning.value = true;
handle = setInterval(callback, interval) as unknown as number;
}

function stop() {
isIntervalRunning.value = false;
clearInterval(handle);
}

Expand All @@ -32,5 +41,9 @@ export const useInterval = (
if (startImmediate) start();
});

return { startInterval: start, stopInterval: stop };
return {
startInterval: start,
stopInterval: stop,
isIntervalRunning: computed(() => isIntervalRunning.value),
larsvanbraam marked this conversation as resolved.
Show resolved Hide resolved
};
};