Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ Vue.use(VueCompositionAPI);
- [`useMouseElement`](./src/components/useMouseElement/stories/useMouseElement.md) — tracks the mouse position relative to given element.
[![Demo](https://img.shields.io/badge/demo-🚀-yellow.svg)](https://microcipcip.github.io/vue-use-kit/?path=/story/sensors-usemouseelement--demo)
- Animations
- [`useInterval`](./src/components/useInterval/stories/useInterval.md) — updates the `counter` value repeatedly on a fixed time delay.
[![Demo](https://img.shields.io/badge/demo-🚀-yellow.svg)](https://microcipcip.github.io/vue-use-kit/?path=/story/animations-useinterval--demo)
- [`useIntervalFn`](./src/components/useIntervalFn/stories/useIntervalFn.md) — calls function repeatedly on a fixed time delay.
[![Demo](https://img.shields.io/badge/demo-🚀-yellow.svg)](https://microcipcip.github.io/vue-use-kit/?path=/story/animations-useintervalfn--demo)
- [`useRaf`](./src/components/useRaf/stories/useRaf.md) — returns `elapsedTime` with requestAnimationFrame.
[![Demo](https://img.shields.io/badge/demo-🚀-yellow.svg)](https://microcipcip.github.io/vue-use-kit/?path=/story/animations-useraf--demo)
- [`useRafFn`](./src/components/useRafFn/stories/useRafFn.md) — calls function with requestAnimationFrame.
Expand Down
1 change: 1 addition & 0 deletions src/components/useInterval/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './useInterval'
41 changes: 41 additions & 0 deletions src/components/useInterval/stories/UseIntervalDemo.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<template>
<table class="table is-fullwidth">
<thead>
<tr>
<th>Prop</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<tr>
<td>counter</td>
<td>
<span>{{ counter }}</span>
</td>
</tr>
<tr>
<td colspan="2">
<button class="button is-primary" @click="start" v-if="!isRunning">
Start Interval
</button>
<button class="button is-danger" @click="stop" v-else>
Stop Interval
</button>
</td>
</tr>
</tbody>
</table>
</template>

<script lang="ts">
import Vue from 'vue'
import { useInterval } from '@src/vue-use-kit'

export default Vue.extend({
name: 'useIntervalDemo',
setup() {
const { isRunning, counter, start, stop } = useInterval(300)
return { isRunning, counter, start, stop }
}
})
</script>
58 changes: 58 additions & 0 deletions src/components/useInterval/stories/useInterval.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# useInterval

Vue function that updates the `counter` value repeatedly on a fixed time delay.

## Reference

```typescript
useInterval(
ms?: number,
runOnMount?: boolean
): {
isRunning: Ref<boolean>;
counter: Ref<number>;
start: () => void;
stop: () => void;
};
```

### Parameters

- `ms: number` how many milliseconds to wait before updating the counter
- `runOnMount: boolean` whether to run the interval on mount, `true` by default

### Returns

- `isRunning: Ref<boolean>` this value is `true` if the interval is running, `false` otherwise
- `counter: Ref<number>` the number of times the interval has run
- `start: Function` the function used for starting the interval
- `stop: Function` the function used for stopping the interval

## Usage

```html
<template>
<div>
<p>counter: {{ counter }}</p>

<button @click="start" v-if="!isRunning">Start Interval</button>
<button @click="stop" v-else>Stop Interval</button>
</div>
</template>

<script lang="ts">
import Vue from 'vue'
import { useInterval } from 'vue-use-kit'

export default Vue.extend({
name: 'UseIntervalDemo',
setup() {
const ms = 300

const { isRunning, counter, start, stop } = useInterval(ms)

return { isRunning, counter, start, stop }
}
})
</script>
```
28 changes: 28 additions & 0 deletions src/components/useInterval/stories/useInterval.story.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { storiesOf } from '@storybook/vue'
import path from 'path'
import StoryTitle from '@src/helpers/StoryTitle.vue'
import UseIntervalDemo from './UseIntervalDemo.vue'

const functionName = 'useInterval'
const functionPath = path.resolve(__dirname, '..')
const notes = require(`./${functionName}.md`).default

const basicDemo = () => ({
components: { StoryTitle, demo: UseIntervalDemo },
template: `
<div class="container">
<story-title
function-path="${functionPath}"
source-name="${functionName}"
demo-name="UseIntervalDemo.vue"
>
<template v-slot:title></template>
<template v-slot:intro></template>
</story-title>
<demo />
</div>`
})

storiesOf('animations|useInterval', module)
.addParameters({ notes })
.add('Demo', basicDemo)
33 changes: 33 additions & 0 deletions src/components/useInterval/useInterval.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { mount } from '@src/helpers/test'
import { useInterval } from '@src/vue-use-kit'

beforeEach(() => {
jest.useFakeTimers()
})

afterEach(() => {
jest.clearAllTimers()
})

const testComponent = () => ({
template: `
<div>
<div id="isRunning" v-if="isRunning"></div>
</div>
`,
setup() {
const { isRunning } = useInterval(1000)
return { isRunning }
}
})

describe('useInterval', () => {
it('should show #isRunning when the intervals are called', async () => {
const wrapper = mount(testComponent())
jest.advanceTimersByTime(1500)

// Wait for Vue to append #isReady in the DOM
await wrapper.vm.$nextTick()
expect(wrapper.find('#isRunning').exists()).toBe(true)
})
})
11 changes: 11 additions & 0 deletions src/components/useInterval/useInterval.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { ref } from '@src/api'
import { useIntervalFn } from '@src/vue-use-kit'

export function useInterval(ms = 0, runOnMount = true) {
const counter = ref(0)
const animHandler = () => {
counter.value = counter.value + 1
}
const { isRunning, start, stop } = useIntervalFn(animHandler, ms, runOnMount)
return { isRunning, counter, start, stop }
}
1 change: 1 addition & 0 deletions src/components/useIntervalFn/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './useIntervalFn'
49 changes: 49 additions & 0 deletions src/components/useIntervalFn/stories/UseIntervalFnDemo.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<template>
<table class="table is-fullwidth">
<thead>
<tr>
<th>Prop</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<tr>
<td>callbackCounter</td>
<td>
<span>{{ callbackCounter }}</span>
</td>
</tr>
<tr>
<td colspan="3">
<button class="button is-primary" @click="start" v-if="!isRunning">
Resume Interval
</button>
<button class="button is-danger" @click="stop" v-else>
Stop Interval
</button>
</td>
</tr>
</tbody>
</table>
</template>

<script lang="ts">
import Vue from 'vue'
import { ref } from '@src/api'
import { useIntervalFn } from '@src/vue-use-kit'

export default Vue.extend({
name: 'UseIntervalFnDemo',
setup() {
const ms = 300
const callbackCounter = ref(0)
const animHandler = () => {
callbackCounter.value = callbackCounter.value + 1
}

const { isRunning, start, stop } = useIntervalFn(animHandler, ms)

return { isRunning, start, stop, callbackCounter }
}
})
</script>
63 changes: 63 additions & 0 deletions src/components/useIntervalFn/stories/useIntervalFn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# useIntervalFn

Vue function that calls given callback repeatedly on a fixed time delay.

## Reference

```typescript
useIntervalFn(
callback: Function,
ms?: number,
runOnMount?: boolean
): {
isRunning: Ref<boolean>;
start: () => void;
stop: () => void;
};
```

### Parameters

- `callback: Function` the function to call for each interval finishes
- `ms: number` how many milliseconds to wait before running the callback function
- `runOnMount: boolean` whether to run the interval on mount, `true` by default

### Returns

- `isRunning: Ref<boolean>` this value is `true` if the interval is running, `false` otherwise
- `start: Function` the function used for starting the interval
- `stop: Function` the function used for stopping the interval

## Usage

```html
<template>
<div>
<p>callbackCounter: {{ callbackCounter }}</p>

<button @click="start" v-if="!isRunning">Start Interval</button>
<button @click="stop" v-else>Stop Interval</button>
</div>
</template>

<script lang="ts">
import Vue from 'vue'
import { ref } from '@src/api'
import { useIntervalFn } from 'vue-use-kit'

export default Vue.extend({
name: 'UseIntervalFnDemo',
setup() {
const ms = 300
const callbackCounter = ref(0)
const animHandler = () => {
callbackCounter.value = callbackCounter.value + 1
}

const { isRunning, start, stop } = useIntervalFn(animHandler, ms)

return { isRunning, start, stop, callbackCounter }
}
})
</script>
```
28 changes: 28 additions & 0 deletions src/components/useIntervalFn/stories/useIntervalFn.story.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { storiesOf } from '@storybook/vue'
import path from 'path'
import StoryTitle from '@src/helpers/StoryTitle.vue'
import UseIntervalFnDemo from './UseIntervalFnDemo.vue'

const functionName = 'useIntervalFn'
const functionPath = path.resolve(__dirname, '..')
const notes = require(`./${functionName}.md`).default

const basicDemo = () => ({
components: { StoryTitle, demo: UseIntervalFnDemo },
template: `
<div class="container">
<story-title
function-path="${functionPath}"
source-name="${functionName}"
demo-name="UseIntervalFnDemo.vue"
>
<template v-slot:title></template>
<template v-slot:intro></template>
</story-title>
<demo />
</div>`
})

storiesOf('animations|useIntervalFn', module)
.addParameters({ notes })
.add('Demo', basicDemo)
Loading