Migrate over time-from-now composition

This commit is contained in:
rijkvanzanten
2020-02-07 15:17:16 -05:00
parent c4f90b724a
commit 98b43cc294
5 changed files with 146 additions and 2 deletions

View File

@@ -1,10 +1,11 @@
# Compositions
Compositions are reusable snippets of functionality that can be used in Vue components.
Compositions are reusable pieces of logic that can be used inside Vue components (Composition API required).
## Table of Contents
* [Event Listener](#event-listener)
* [Time from Now](#time-from-now)
* [Window Size](#window-size)
## Event Listener
@@ -32,6 +33,27 @@ export default createComponent({
});
```
## Time from Now
Returns ref string time from current datetime based on date-fns formatDistance.
### Usage
```js
import { createComponent } from '@vue/composition-api';
import useTimeFromNow from '@/compositions/time-from-now';
export default createComponent({
setup() {
const date = new Date('2020-01-01T13:55');
const timeFromNow = useTimeFromNow(date);
}
});
```
The composition accepts an optional second parameter that controls how often the value is update. You can set this to `0` if you don't want the value to update at all.
## Window Size
Returns a `ref` of `width` and `height` of the current window size. Updates the value on window resizes.

View File

@@ -0,0 +1,90 @@
import { Ref } from '@vue/composition-api';
import useTimeFromNow from './time-from-now';
import mountComposition from '../../.jest/mount-composition';
import mockdate from 'mockdate';
describe('Compositions / Event Listener', () => {
beforeEach(() => {
jest.useFakeTimers();
});
afterEach(() => {
mockdate.reset();
});
it('Formats the date relative', () => {
const now = new Date();
let timeAgo: Ref<string>;
let timeAhead: Ref<string>;
mountComposition(() => {
timeAgo = useTimeFromNow(new Date(now.getTime() - 5 * 60 * 1000));
timeAhead = useTimeFromNow(new Date(now.getTime() + 5 * 60 * 1000));
});
expect(timeAgo!.value).toBe('5 minutes ago');
expect(timeAhead!.value).toBe('in 5 minutes');
});
it('Updates the ref every minute by default', () => {
mockdate.set('2020-01-01T12:00:00');
const now = new Date();
const component = mountComposition(() => {
const timeAgo = useTimeFromNow(new Date(now.getTime() - 5 * 60 * 1000));
return { timeAgo };
});
expect((component.vm as any).timeAgo).toBe('5 minutes ago');
mockdate.set('2020-01-01T12:01:00');
jest.runTimersToTime(60000);
expect(setInterval).toHaveBeenCalledTimes(1);
expect((component.vm as any).timeAgo).toBe('6 minutes ago');
});
it('Does not automatically update if 0 is passed for autoUpdate param', () => {
mockdate.set('2020-01-01T12:00:00');
const now = new Date();
const component = mountComposition(() => {
const timeAgo = useTimeFromNow(new Date(now.getTime() - 5 * 60 * 1000), 0);
return { timeAgo };
});
expect((component.vm as any).timeAgo).toBe('5 minutes ago');
mockdate.set('2020-01-01T12:01:00');
jest.runTimersToTime(60000);
expect(setInterval).toHaveBeenCalledTimes(0);
expect((component.vm as any).timeAgo).toBe('5 minutes ago');
});
it('Clears the interval when the component is unmounted', () => {
mockdate.set('2020-01-01T12:00:00');
const now = new Date();
const component = mountComposition(() => {
const timeAgo = useTimeFromNow(new Date(now.getTime() - 5 * 60 * 1000));
return { timeAgo };
});
expect((component.vm as any).timeAgo).toBe('5 minutes ago');
mockdate.set('2020-01-01T12:01:00');
jest.runTimersToTime(60000);
expect(setInterval).toHaveBeenCalledTimes(1);
component.destroy();
mockdate.set('2020-01-01T12:01:00');
jest.runTimersToTime(60000);
expect(setInterval).toHaveBeenCalledTimes(1);
});
});

View File

@@ -0,0 +1,26 @@
import { onMounted, onUnmounted, ref } from '@vue/composition-api';
import formatDistance from 'date-fns/formatDistance';
export default function useFormatDistance(date: Date | number, autoUpdate: number = 60000) {
let interval: number;
const formatOptions = {
addSuffix: true
};
const formattedDate = ref(formatDistance(date, new Date(), formatOptions));
if (autoUpdate !== 0) {
onMounted(() => {
interval = setInterval(() => {
formattedDate.value = formatDistance(date, new Date(), formatOptions);
}, autoUpdate);
});
onUnmounted(() => {
clearInterval(interval);
});
}
return formattedDate;
}