+
Below field is valid only if number is even
+
) => {
+ setState(ev.target.value);
+ }}
+ />
+ {isValid !== null &&
{isValid ? 'Valid!' : 'Invalid'} }
+
+ );
+};
+```
+
+## Reference
+```ts
+const [validity, revalidate] = useStateValidator(
+ state: any,
+ validator: (state, setValidity?)=>[boolean|null, ...any[]],
+ initialValidity: any
+);
+```
+- **`validity`**_`: [boolean|null, ...any[]]`_ result of validity check. First element is strictly nullable boolean, but others can contain arbitrary data;
+- **`revalidate`**_`: ()=>void`_ runs validator once again
+- **`validator`**_`: (state, setValidity?)=>[boolean|null, ...any[]]`_ should return an array suitable for validity state described above;
+ - `state` - current state;
+ - `setValidity` - if defined hook will not trigger validity change automatically. Useful for async validators;
+- `initialValidity` - validity value which set when validity is nt calculated yet;
diff --git a/docs/useToggle.md b/docs/useToggle.md
index e1a342e7..0405c6ce 100644
--- a/docs/useToggle.md
+++ b/docs/useToggle.md
@@ -7,7 +7,7 @@ React state hook that tracks value of a boolean.
## Usage
```jsx
-import {useToggle, useBoolean} from 'react-use';
+import {useToggle} from 'react-use';
const Demo = () => {
const [on, toggle] = useToggle(true);
diff --git a/docs/useUpsert.md b/docs/useUpsert.md
index 2384660d..48c3de55 100644
--- a/docs/useUpsert.md
+++ b/docs/useUpsert.md
@@ -1,6 +1,7 @@
# `useUpsert`
-Superset of `useList`. Provides an additional method to upsert (update or insert) an element into the list.
+Superset of [`useList`](./useList.md). Provides an additional method to upsert (update or insert) an element into the list.
+
## Usage
```jsx
@@ -26,3 +27,7 @@ const Demo = () => {
);
};
```
+
+## Related hooks
+
+- [useList](./useList.md)
diff --git a/package.json b/package.json
index 7e5f9d34..82941fbf 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "react-use",
- "version": "12.2.0",
+ "version": "12.5.0",
"description": "Collection of React Hooks",
"main": "lib/index.js",
"module": "esm/index.js",
@@ -51,7 +51,7 @@
"react-fast-compare": "^2.0.4",
"react-wait": "^0.3.0",
"resize-observer-polyfill": "^1.5.1",
- "screenfull": "^4.1.0",
+ "screenfull": "^5.0.0",
"set-harmonic-interval": "^1.0.0",
"throttle-debounce": "^2.0.1",
"ts-easing": "^0.2.0",
@@ -62,52 +62,53 @@
"react-dom": "^16.8.0"
},
"devDependencies": {
- "@babel/core": "7.6.0",
+ "@babel/core": "7.6.4",
"@babel/plugin-syntax-dynamic-import": "7.2.0",
- "@babel/preset-env": "7.6.0",
- "@babel/preset-react": "7.0.0",
+ "@babel/preset-env": "7.6.3",
+ "@babel/preset-react": "7.6.3",
"@babel/preset-typescript": "7.6.0",
"@semantic-release/changelog": "3.0.4",
"@semantic-release/git": "7.0.16",
"@semantic-release/npm": "5.1.13",
+ "@shopify/jest-dom-mocks": "2.8.2",
"@storybook/addon-actions": "5.1.11",
"@storybook/addon-knobs": "5.1.11",
"@storybook/addon-notes": "5.1.11",
"@storybook/addon-options": "5.1.11",
"@storybook/react": "5.1.11",
- "@testing-library/react-hooks": "2.0.1",
+ "@testing-library/react-hooks": "2.0.3",
"@types/jest": "24.0.18",
"@types/react": "16.9.2",
"babel-core": "6.26.3",
"babel-loader": "8.0.6",
"babel-plugin-dynamic-import-node": "2.3.0",
- "fork-ts-checker-webpack-plugin": "1.5.0",
+ "fork-ts-checker-webpack-plugin": "1.5.1",
"gh-pages": "2.1.1",
- "husky": "3.0.5",
+ "husky": "3.0.9",
"jest": "24.9.0",
"keyboardjs": "2.5.1",
- "lint-staged": "9.2.5",
+ "lint-staged": "9.4.2",
"markdown-loader": "5.1.0",
"prettier": "1.18.2",
"raf-stub": "3.0.0",
- "react": "16.9.0",
- "react-dom": "16.9.0",
+ "react": "16.10.2",
+ "react-dom": "16.10.2",
"react-frame-component": "4.1.1",
"react-spring": "8.0.27",
- "react-test-renderer": "16.9.0",
+ "react-test-renderer": "16.10.2",
"rebound": "0.1.0",
"redux-logger": "3.0.6",
"redux-thunk": "2.3.0",
"rimraf": "3.0.0",
"rxjs": "6.5.3",
"semantic-release": "15.13.24",
- "ts-loader": "6.1.0",
- "ts-node": "8.3.0",
+ "ts-loader": "6.2.0",
+ "ts-node": "8.4.1",
"tslint": "5.20.0",
"tslint-config-prettier": "1.18.0",
"tslint-eslint-rules": "5.4.0",
"tslint-plugin-prettier": "2.0.1",
- "tslint-react": "4.0.0",
+ "tslint-react": "4.1.0",
"typescript": "3.5.3"
},
"config": {
@@ -141,8 +142,8 @@
]
},
"volta": {
- "node": "10.16.0",
- "yarn": "1.16.0"
+ "node": "10.16.3",
+ "yarn": "1.19.1"
},
"collective": {
"type": "opencollective",
diff --git a/src/__stories__/useIntersection.story.tsx b/src/__stories__/useIntersection.story.tsx
new file mode 100644
index 00000000..fb8c1226
--- /dev/null
+++ b/src/__stories__/useIntersection.story.tsx
@@ -0,0 +1,53 @@
+import { storiesOf } from '@storybook/react';
+import * as React from 'react';
+import { useIntersection } from '..';
+import ShowDocs from './util/ShowDocs';
+
+const Spacer = () => (
+
);
diff --git a/src/__stories__/useList.story.tsx b/src/__stories__/useList.story.tsx
index 912552a2..2ccfb611 100644
--- a/src/__stories__/useList.story.tsx
+++ b/src/__stories__/useList.story.tsx
@@ -4,13 +4,20 @@ import { useList } from '..';
import ShowDocs from './util/ShowDocs';
const Demo = () => {
- const [list, { set, push }] = useList();
+ const [list, { clear, filter, push, remove, set, sort, updateAt, reset }] = useList([1, 2, 3, 4, 5]);
return (
-
{JSON.stringify(map, null, 2)}
set(String(Date.now()), new Date().toJSON())}>Add
reset()}>Reset
+
remove('hello')} disabled={!map.hello}>
+ Remove 'hello'
+
+
{JSON.stringify(map, null, 2)}
);
};
diff --git a/src/__stories__/useMeasure.story.tsx b/src/__stories__/useMeasure.story.tsx
index c91fa18b..2431f993 100644
--- a/src/__stories__/useMeasure.story.tsx
+++ b/src/__stories__/useMeasure.story.tsx
@@ -4,18 +4,12 @@ import { useMeasure } from '..';
import ShowDocs from './util/ShowDocs';
const Demo = () => {
- const [ref, { width, height }] = useMeasure();
+ const [ref, state] = useMeasure();
return (
<>
-
+
{JSON.stringify(state, null, 2)}
+
resize me
>
diff --git a/src/__stories__/useSize.story.tsx b/src/__stories__/useSize.story.tsx
index c029359a..9310b377 100644
--- a/src/__stories__/useSize.story.tsx
+++ b/src/__stories__/useSize.story.tsx
@@ -4,15 +4,14 @@ import { useSize } from '..';
import ShowDocs from './util/ShowDocs';
const Demo = () => {
- const [sized, { width, height }] = useSize(({ width: currentWidth }) => (
-
Size me up! ({currentWidth}px)
+ const [sized, state] = useSize(({ width: currentWidth }) => (
+
Size me up! ({currentWidth}px)
));
return (
+
{JSON.stringify(state, null, 2)}
{sized}
-
width: {width}
-
height: {height}
);
};
diff --git a/src/__stories__/useStateValidator.story.tsx b/src/__stories__/useStateValidator.story.tsx
new file mode 100644
index 00000000..906de0cb
--- /dev/null
+++ b/src/__stories__/useStateValidator.story.tsx
@@ -0,0 +1,30 @@
+import { storiesOf } from '@storybook/react';
+import * as React from 'react';
+import useStateValidator from '../useStateValidator';
+import ShowDocs from './util/ShowDocs';
+
+const DemoStateValidator = s => [s === '' ? null : (s * 1) % 2 === 0];
+const Demo = () => {
+ const [state, setState] = React.useState
(0);
+ const [[isValid]] = useStateValidator(state, DemoStateValidator);
+
+ return (
+
+
Below field is valid only if number is even
+
) => {
+ setState(ev.target.value);
+ }}
+ />
+ {isValid !== null &&
{isValid ? 'Valid!' : 'Invalid'} }
+
+ );
+};
+
+storiesOf('State|useStateValidator', module)
+ .add('Docs', () => )
+ .add('Demo', () => );
diff --git a/src/__tests__/useDeepCompareEffect.test.ts b/src/__tests__/useDeepCompareEffect.test.ts
new file mode 100644
index 00000000..965495de
--- /dev/null
+++ b/src/__tests__/useDeepCompareEffect.test.ts
@@ -0,0 +1,39 @@
+import { renderHook } from '@testing-library/react-hooks';
+import { useDeepCompareEffect } from '..';
+import { useEffect } from 'react';
+
+let options = { max: 10 };
+const mockEffectNormal = jest.fn();
+const mockEffectDeep = jest.fn();
+const mockEffectCleanup = jest.fn();
+const mockEffectCallback = jest.fn().mockReturnValue(mockEffectCleanup);
+
+it('should run provided object once', () => {
+ const { rerender: rerenderNormal } = renderHook(() => useEffect(mockEffectNormal, [options]));
+ const { rerender: rerenderDeep } = renderHook(() => useDeepCompareEffect(mockEffectDeep, [options]));
+
+ expect(mockEffectNormal).toHaveBeenCalledTimes(1);
+ expect(mockEffectDeep).toHaveBeenCalledTimes(1);
+
+ options = { max: 10 };
+ rerenderDeep();
+ rerenderNormal();
+
+ expect(mockEffectNormal).toHaveBeenCalledTimes(2);
+ expect(mockEffectDeep).toHaveBeenCalledTimes(1);
+
+ options = { max: 10 };
+ rerenderNormal();
+ rerenderDeep();
+
+ expect(mockEffectNormal).toHaveBeenCalledTimes(3);
+ expect(mockEffectDeep).toHaveBeenCalledTimes(1);
+});
+
+it('should run clean-up provided on unmount', () => {
+ const { unmount } = renderHook(() => useDeepCompareEffect(mockEffectCallback, [options]));
+ expect(mockEffectCleanup).not.toHaveBeenCalled();
+
+ unmount();
+ expect(mockEffectCleanup).toHaveBeenCalledTimes(1);
+});
diff --git a/src/__tests__/useFavicon.test.tsx b/src/__tests__/useFavicon.test.tsx
new file mode 100644
index 00000000..fcbbda43
--- /dev/null
+++ b/src/__tests__/useFavicon.test.tsx
@@ -0,0 +1,55 @@
+import { renderHook } from '@testing-library/react-hooks';
+import useFavicon from '../useFavicon';
+
+afterEach(() => {
+ const favicon = document.querySelector("link[rel*='icon']");
+ if (favicon) {
+ favicon.remove();
+ }
+});
+
+describe('useFavicon', () => {
+ it('should be defined', () => {
+ expect(useFavicon).toBeDefined();
+ });
+
+ it('should create a HTMLLinkElement', () => {
+ const faviconBeforeHook = document.querySelector("link[rel*='icon']");
+
+ expect(faviconBeforeHook).toBe(null);
+ renderHook(() => useFavicon('My-favicon'));
+
+ const faviconAfterHook = document.querySelector("link[rel*='icon']");
+ expect(faviconAfterHook).toBeInstanceOf(HTMLLinkElement);
+ });
+
+ it('should set the elements type to "image/x-icon"', () => {
+ renderHook(() => useFavicon('My-favicon'));
+ const favicon = document.querySelector("link[rel*='icon']") as HTMLLinkElement;
+
+ expect(favicon.type).toBe('image/x-icon');
+ });
+
+ it('should set the elements rel to "shortcut icon"', () => {
+ renderHook(() => useFavicon('My-favicon'));
+ const favicon = document.querySelector("link[rel*='icon']") as HTMLLinkElement;
+
+ expect(favicon.rel).toBe('shortcut icon');
+ });
+
+ it('should set the elements href to the provided string', () => {
+ renderHook(() => useFavicon('https://github.com/streamich/react-use'));
+ const favicon = document.querySelector("link[rel*='icon']") as HTMLLinkElement;
+
+ expect(favicon.href).toBe('https://github.com/streamich/react-use');
+ });
+
+ it('should update an existing favicon', () => {
+ const hook = renderHook(props => useFavicon(props), { initialProps: 'https://github.com/streamich/react-use' });
+ const favicon = document.querySelector("link[rel*='icon']") as HTMLLinkElement;
+
+ expect(favicon.href).toBe('https://github.com/streamich/react-use');
+ hook.rerender('https://en.wikipedia.org/wiki/Favicon');
+ expect(favicon.href).toBe('https://en.wikipedia.org/wiki/Favicon');
+ });
+});
diff --git a/src/__tests__/useIntersection.test.tsx b/src/__tests__/useIntersection.test.tsx
new file mode 100644
index 00000000..ee7342b2
--- /dev/null
+++ b/src/__tests__/useIntersection.test.tsx
@@ -0,0 +1,119 @@
+import React, { createRef } from 'react';
+import ReactDOM from 'react-dom';
+import TestUtils from 'react-dom/test-utils';
+import TestRenderer from 'react-test-renderer';
+import { intersectionObserver } from '@shopify/jest-dom-mocks';
+import { renderHook } from '@testing-library/react-hooks';
+import { useIntersection } from '..';
+
+beforeEach(() => {
+ intersectionObserver.mock();
+});
+
+afterEach(() => {
+ intersectionObserver.restore();
+});
+
+describe('useIntersection', () => {
+ const container = document.createElement('div');
+ let targetRef;
+
+ it('should be defined', () => {
+ expect(useIntersection).toBeDefined();
+ });
+
+ it('should setup an IntersectionObserver targeting the ref element and using the options provided', () => {
+ TestUtils.act(() => {
+ targetRef = createRef();
+ ReactDOM.render(
, container);
+ });
+
+ expect(intersectionObserver.observers).toHaveLength(0);
+ const observerOptions = { root: null, threshold: 0.8 };
+
+ renderHook(() => useIntersection(targetRef, observerOptions));
+
+ expect(intersectionObserver.observers).toHaveLength(1);
+ expect(intersectionObserver.observers[0].target).toEqual(targetRef.current);
+ expect(intersectionObserver.observers[0].options).toEqual(observerOptions);
+ });
+
+ it('should return null if a ref without a current value is provided', () => {
+ targetRef = createRef();
+
+ const { result } = renderHook(() => useIntersection(targetRef, { root: null, threshold: 1 }));
+ expect(result.current).toBe(null);
+ });
+
+ it('should return the first IntersectionObserverEntry when the IntersectionObserver registers an intersection', () => {
+ TestUtils.act(() => {
+ targetRef = createRef();
+ ReactDOM.render(
, container);
+ });
+
+ const { result } = renderHook(() => useIntersection(targetRef, { root: container, threshold: 0.8 }));
+
+ const mockIntersectionObserverEntry = {
+ boundingClientRect: targetRef.current.getBoundingClientRect(),
+ intersectionRatio: 0.81,
+ intersectionRect: container.getBoundingClientRect(),
+ isIntersecting: true,
+ rootBounds: container.getBoundingClientRect(),
+ target: targetRef.current,
+ time: 300,
+ };
+ TestRenderer.act(() => {
+ intersectionObserver.simulate(mockIntersectionObserverEntry);
+ });
+
+ expect(result.current).toEqual(mockIntersectionObserverEntry);
+ });
+
+ it('should setup a new IntersectionObserver when the ref changes', () => {
+ let newRef;
+ TestUtils.act(() => {
+ targetRef = createRef();
+ newRef = createRef();
+ ReactDOM.render(
+
+
+
,
+ container
+ );
+ });
+
+ const observerOptions = { root: null, threshold: 0.8 };
+ const { rerender } = renderHook(({ ref, options }) => useIntersection(ref, options), {
+ initialProps: { ref: targetRef, options: observerOptions },
+ });
+
+ expect(intersectionObserver.observers[0].target).toEqual(targetRef.current);
+
+ TestRenderer.act(() => {
+ rerender({ ref: newRef, options: observerOptions });
+ });
+
+ expect(intersectionObserver.observers[0].target).toEqual(newRef.current);
+ });
+
+ it('should setup a new IntersectionObserver when the options change', () => {
+ TestUtils.act(() => {
+ targetRef = createRef();
+ ReactDOM.render(
, container);
+ });
+
+ const initialObserverOptions = { root: null, threshold: 0.8 };
+ const { rerender } = renderHook(({ ref, options }) => useIntersection(ref, options), {
+ initialProps: { ref: targetRef, options: initialObserverOptions },
+ });
+
+ expect(intersectionObserver.observers[0].options).toEqual(initialObserverOptions);
+
+ const newObserverOptions = { root: container, threshold: 1 };
+ TestRenderer.act(() => {
+ rerender({ ref: targetRef, options: newObserverOptions });
+ });
+
+ expect(intersectionObserver.observers[0].options).toEqual(newObserverOptions);
+ });
+});
diff --git a/src/__tests__/useList.test.ts b/src/__tests__/useList.test.ts
index 047e6e68..47b5beb7 100644
--- a/src/__tests__/useList.test.ts
+++ b/src/__tests__/useList.test.ts
@@ -16,6 +16,7 @@ it('should init list and utils', () => {
push: expect.any(Function),
filter: expect.any(Function),
sort: expect.any(Function),
+ reset: expect.any(Function),
});
});
@@ -103,6 +104,19 @@ it('should push duplicated element at the end of the list', () => {
expect(result.current[0]).not.toBe(initList); // checking immutability
});
+it('should push multiple elements at the end of the list', () => {
+ const initList = [1, 2, 3];
+ const { result } = setUp(initList);
+ const [, utils] = result.current;
+
+ act(() => {
+ utils.push(4, 5, 6);
+ });
+
+ expect(result.current[0]).toEqual([1, 2, 3, 4, 5, 6]);
+ expect(result.current[0]).not.toBe(initList); // checking immutability
+});
+
it('should filter current list by provided function', () => {
const initList = [1, -1, 2, -2, 3, -3];
const { result } = setUp(initList);
@@ -150,3 +164,43 @@ it('should sort current list by provided function', () => {
expect(result.current[0]).toEqual(['March', 'Jan', 'Feb', 'Dec']);
expect(result.current[0]).not.toBe(initList); // checking immutability
});
+
+it('should reset the list to initial list provided', () => {
+ const initList = [1, 2, 3];
+ const { result } = setUp(initList);
+ const [, utils] = result.current;
+
+ act(() => {
+ utils.push(4);
+ });
+
+ expect(result.current[0]).toEqual([1, 2, 3, 4]);
+
+ act(() => {
+ utils.reset();
+ });
+
+ expect(result.current[0]).toEqual([1, 2, 3]);
+ expect(result.current[0]).not.toBe(initList); // checking immutability
+});
+
+it('should memoized its utils methods', () => {
+ const initList = [1, 2, 3];
+ const { result } = setUp(initList);
+ const [, utils] = result.current;
+ const { set, clear, updateAt, remove, push, filter, sort, reset } = utils;
+
+ act(() => {
+ push(4);
+ });
+
+ expect(result.current[1]).toBe(utils);
+ expect(result.current[1].set).toBe(set);
+ expect(result.current[1].clear).toBe(clear);
+ expect(result.current[1].updateAt).toBe(updateAt);
+ expect(result.current[1].remove).toBe(remove);
+ expect(result.current[1].push).toBe(push);
+ expect(result.current[1].filter).toBe(filter);
+ expect(result.current[1].sort).toBe(sort);
+ expect(result.current[1].reset).toBe(reset);
+});
diff --git a/src/__tests__/useLogger.test.ts b/src/__tests__/useLogger.test.ts
new file mode 100644
index 00000000..85989b9f
--- /dev/null
+++ b/src/__tests__/useLogger.test.ts
@@ -0,0 +1,41 @@
+import { renderHook } from '@testing-library/react-hooks';
+import useLogger from '../useLogger';
+
+const logSpy = jest.spyOn(global.console, 'log').mockImplementation(() => {});
+
+describe('useLogger', () => {
+ it('should be defined', () => {
+ expect(useLogger).toBeDefined();
+ });
+
+ it('should log the provided props on mount', () => {
+ const props = { question: 'What is the meaning?', answer: 42 };
+ renderHook(() => useLogger('Test', props));
+
+ expect(logSpy).toBeCalledTimes(1);
+ expect(logSpy).toHaveBeenLastCalledWith('Test mounted', props);
+ });
+
+ it('should log when the component has unmounted', () => {
+ const props = { question: 'What is the meaning?', answer: 42 };
+ const { unmount } = renderHook(() => useLogger('Test', props));
+
+ unmount();
+
+ expect(logSpy).toHaveBeenLastCalledWith('Test unmounted');
+ });
+
+ it('should log updates as props change', () => {
+ const { rerender } = renderHook(
+ ({ componentName, props }: { componentName: string; props: any }) => useLogger(componentName, props),
+ {
+ initialProps: { componentName: 'Test', props: { one: 1 } },
+ }
+ );
+
+ const newProps = { one: 1, two: 2 };
+ rerender({ componentName: 'Test', props: newProps });
+
+ expect(logSpy).toHaveBeenLastCalledWith('Test updated', newProps);
+ });
+});
diff --git a/src/__tests__/useStateValidator.test.ts b/src/__tests__/useStateValidator.test.ts
new file mode 100644
index 00000000..7b717541
--- /dev/null
+++ b/src/__tests__/useStateValidator.test.ts
@@ -0,0 +1,100 @@
+import { act, renderHook, RenderHookResult } from '@testing-library/react-hooks';
+import { useState } from 'react';
+import useStateValidator, { UseValidatorReturn, Validator } from '../useStateValidator';
+
+interface Mock extends jest.Mock {}
+
+describe('useStateValidator', () => {
+ it('should be defined', () => {
+ expect(useStateValidator).toBeDefined();
+ });
+
+ function getHook(
+ fn: Validator = jest.fn(state => [!!(state % 2)])
+ ): [jest.Mock | Function, RenderHookResult]>] {
+ return [
+ fn,
+ renderHook(() => {
+ const [state, setState] = useState(1);
+
+ return [setState, useStateValidator(state, fn)];
+ }),
+ ];
+ }
+
+ it('should return an array of two elements', () => {
+ const [, hook] = getHook();
+ const res = hook.result.current[1];
+
+ expect(Array.isArray(res)).toBe(true);
+ expect(res[0]).toEqual([true]);
+ expect(typeof res[1]).toBe('function');
+ });
+
+ it('first element should represent current validity state', () => {
+ const [, hook] = getHook();
+ let [setState, [validity]] = hook.result.current;
+ expect(validity).toEqual([true]);
+
+ act(() => setState(3));
+ [setState, [validity]] = hook.result.current;
+ expect(validity).toEqual([true]);
+
+ act(() => setState(4));
+ [setState, [validity]] = hook.result.current;
+ expect(validity).toEqual([false]);
+ });
+
+ it('second element should re-call validation', () => {
+ const [spy, hook] = getHook();
+ const [, [, revalidate]] = hook.result.current;
+
+ expect(spy).toHaveBeenCalledTimes(1);
+ act(() => revalidate());
+ expect(spy).toHaveBeenCalledTimes(2);
+ });
+
+ it('validator have to be called on init plus on each state update', () => {
+ const [spy, hook] = getHook(jest.fn());
+ const [setState] = hook.result.current;
+
+ expect(spy).toHaveBeenCalledTimes(1);
+ act(() => setState(4));
+ expect(spy).toHaveBeenCalledTimes(2);
+ act(() => setState(prevState => prevState + 1));
+ expect(spy).toHaveBeenCalledTimes(3);
+ });
+
+ it('should pass to validator one parameter - current state', () => {
+ const [spy, hook] = getHook(jest.fn());
+ const [setState] = hook.result.current;
+
+ act(() => setState(4));
+ act(() => setState(5));
+ expect((spy as Mock).mock.calls[0].length).toBe(1);
+ expect((spy as Mock).mock.calls[0].length).toBe(1);
+ expect((spy as Mock).mock.calls[0][0]).toBe(1);
+ expect((spy as Mock).mock.calls[1].length).toBe(1);
+ expect((spy as Mock).mock.calls[1][0]).toBe(4);
+ expect((spy as Mock).mock.calls[2].length).toBe(1);
+ expect((spy as Mock).mock.calls[2][0]).toBe(5);
+ });
+
+ it('if validator expects 2nd parameters it should pass a validity setter there', () => {
+ const [spy, hook] = getHook(jest.fn((state, setValidity) => setValidity!([state % 2 === 0])));
+ let [setState, [[isValid]]] = hook.result.current;
+
+ expect((spy as Mock).mock.calls[0].length).toBe(2);
+ expect(typeof (spy as Mock).mock.calls[0][1]).toBe('function');
+
+ expect(isValid).toBe(false);
+ act(() => setState(prevState => prevState + 1));
+
+ [setState, [[isValid]]] = hook.result.current;
+ expect(isValid).toBe(true);
+ act(() => setState(5));
+
+ [setState, [[isValid]]] = hook.result.current;
+ expect(isValid).toBe(false);
+ });
+});
diff --git a/src/__tests__/useUpdateEffect.test.ts b/src/__tests__/useUpdateEffect.test.ts
new file mode 100644
index 00000000..933395d4
--- /dev/null
+++ b/src/__tests__/useUpdateEffect.test.ts
@@ -0,0 +1,13 @@
+import { renderHook } from '@testing-library/react-hooks';
+import { useUpdateEffect } from '..';
+
+const mockEffectCleanup = jest.fn();
+const mockEffectCallback = jest.fn().mockReturnValue(mockEffectCleanup);
+
+it('should run effect on update', () => {
+ const { rerender } = renderHook(() => useUpdateEffect(mockEffectCallback));
+ expect(mockEffectCallback).not.toHaveBeenCalled();
+
+ rerender();
+ expect(mockEffectCallback).toHaveBeenCalledTimes(1);
+});
diff --git a/src/index.ts b/src/index.ts
index b3514a71..65872134 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -27,6 +27,7 @@ export { default as useHarmonicIntervalFn } from './useHarmonicIntervalFn';
export { default as useHover } from './useHover';
export { default as useHoverDirty } from './useHoverDirty';
export { default as useIdle } from './useIdle';
+export { default as useIntersection } from './useIntersection';
export { default as useInterval } from './useInterval';
export { default as useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect';
export { default as useKey } from './useKey';
@@ -86,6 +87,7 @@ export { default as useUpdate } from './useUpdate';
export { default as useUpdateEffect } from './useUpdateEffect';
export { default as useUpsert } from './useUpsert';
export { default as useVideo } from './useVideo';
+export { default as useStateValidator } from './useStateValidator';
export { useWait, Waiter } from './useWait';
export { default as useWindowScroll } from './useWindowScroll';
export { default as useWindowSize } from './useWindowSize';
diff --git a/src/useAsyncRetry.ts b/src/useAsyncRetry.ts
index 1c11578f..519c2b5d 100644
--- a/src/useAsyncRetry.ts
+++ b/src/useAsyncRetry.ts
@@ -20,7 +20,7 @@ const useAsyncRetry = (fn: () => Promise, deps: DependencyList = []) => {
}
setAttempt(currentAttempt => currentAttempt + 1);
- }, [...deps, stateLoading, attempt]);
+ }, [...deps, stateLoading]);
return { ...state, retry };
};
diff --git a/src/useDebounce.ts b/src/useDebounce.ts
index 3c7d4664..bb7bffb7 100644
--- a/src/useDebounce.ts
+++ b/src/useDebounce.ts
@@ -1,14 +1,14 @@
+import { DependencyList } from 'react';
import useUpdateEffect from './useUpdateEffect';
-const useDebounce = (fn: () => any, ms: number = 0, args: any[] = []) => {
+const useDebounce = (fn: () => any, ms: number = 0, deps: DependencyList = []) => {
useUpdateEffect(() => {
- const handle = setTimeout(fn.bind(null, args), ms);
+ const timeout = setTimeout(fn, ms);
return () => {
- // if args change then clear timeout
- clearTimeout(handle);
+ clearTimeout(timeout);
};
- }, args);
+ }, deps);
};
export default useDebounce;
diff --git a/src/useFullscreen.ts b/src/useFullscreen.ts
index 52f63705..c55b0d3d 100644
--- a/src/useFullscreen.ts
+++ b/src/useFullscreen.ts
@@ -26,7 +26,7 @@ const useFullscreen = (ref: RefObject, on: boolean, options: FullScreen
};
const onChange = () => {
- if (screenfull) {
+ if (screenfull.isEnabled) {
const isScreenfullFullscreen = screenfull.isFullscreen;
setIsFullscreen(isScreenfullFullscreen);
if (!isScreenfullFullscreen) {
@@ -35,7 +35,7 @@ const useFullscreen = (ref: RefObject, on: boolean, options: FullScreen
}
};
- if (screenfull && screenfull.enabled) {
+ if (screenfull.isEnabled) {
try {
screenfull.request(ref.current);
setIsFullscreen(true);
@@ -55,7 +55,7 @@ const useFullscreen = (ref: RefObject, on: boolean, options: FullScreen
return () => {
setIsFullscreen(false);
- if (screenfull && screenfull.enabled) {
+ if (screenfull.isEnabled) {
try {
screenfull.off('change', onChange);
screenfull.exit();
@@ -65,7 +65,7 @@ const useFullscreen = (ref: RefObject, on: boolean, options: FullScreen
video.current.webkitExitFullscreen();
}
};
- }, [ref.current, video, on]);
+ }, [on, video, ref]);
return isFullscreen;
};
diff --git a/src/useIntersection.ts b/src/useIntersection.ts
new file mode 100644
index 00000000..4a7b78ea
--- /dev/null
+++ b/src/useIntersection.ts
@@ -0,0 +1,30 @@
+import { RefObject, useEffect, useState } from 'react';
+
+const useIntersection = (
+ ref: RefObject,
+ options: IntersectionObserverInit
+): IntersectionObserverEntry | null => {
+ const [intersectionObserverEntry, setIntersectionObserverEntry] = useState(null);
+
+ useEffect(() => {
+ if (ref.current) {
+ const handler = (entries: IntersectionObserverEntry[]) => {
+ setIntersectionObserverEntry(entries[0]);
+ };
+
+ const observer = new IntersectionObserver(handler, options);
+ observer.observe(ref.current);
+
+ return () => {
+ if (ref.current) {
+ observer.disconnect();
+ }
+ };
+ }
+ return () => {};
+ }, [ref, options.threshold, options.root, options.rootMargin]);
+
+ return intersectionObserverEntry;
+};
+
+export default useIntersection;
diff --git a/src/useInterval.ts b/src/useInterval.ts
index f411cc74..4613d5e9 100644
--- a/src/useInterval.ts
+++ b/src/useInterval.ts
@@ -1,17 +1,18 @@
import { useEffect, useRef } from 'react';
const useInterval = (callback: Function, delay?: number | null) => {
- const latestCallback = useRef(() => {});
+ const savedCallback = useRef(() => {});
useEffect(() => {
- latestCallback.current = callback;
+ savedCallback.current = callback;
});
useEffect(() => {
if (delay !== null) {
- const interval = setInterval(() => latestCallback.current(), delay || 0);
+ const interval = setInterval(() => savedCallback.current(), delay || 0);
return () => clearInterval(interval);
}
+
return undefined;
}, [delay]);
};
diff --git a/src/useList.ts b/src/useList.ts
index 5e292987..eecdc507 100644
--- a/src/useList.ts
+++ b/src/useList.ts
@@ -1,31 +1,35 @@
-import { useState } from 'react';
+import { useState, useMemo } from 'react';
export interface Actions {
set: (list: T[]) => void;
clear: () => void;
updateAt: (index: number, item: T) => void;
remove: (index: number) => void;
- push: (item: T) => void;
+ push: (...items: T[]) => void;
filter: (fn: (value: T) => boolean) => void;
sort: (fn?: (a: T, b: T) => number) => void;
+ reset: () => void;
}
const useList = (initialList: T[] = []): [T[], Actions] => {
const [list, set] = useState(initialList);
- return [
- list,
- {
+ const utils = useMemo>(
+ () => ({
set,
clear: () => set([]),
updateAt: (index, entry) =>
set(currentList => [...currentList.slice(0, index), entry, ...currentList.slice(index + 1)]),
remove: index => set(currentList => [...currentList.slice(0, index), ...currentList.slice(index + 1)]),
- push: entry => set(currentList => [...currentList, entry]),
+ push: (...entry) => set(currentList => [...currentList, ...entry]),
filter: fn => set(currentList => currentList.filter(fn)),
sort: (fn?) => set(currentList => [...currentList].sort(fn)),
- },
- ];
+ reset: () => set([...initialList]),
+ }),
+ [set]
+ );
+
+ return [list, utils];
};
export default useList;
diff --git a/src/useMouse.ts b/src/useMouse.ts
index 7e692a8d..665a126b 100644
--- a/src/useMouse.ts
+++ b/src/useMouse.ts
@@ -62,7 +62,7 @@ const useMouse = (ref: RefObject): State => {
cancelAnimationFrame(frame.current);
document.removeEventListener('mousemove', moveHandler);
};
- }, [ref.current]);
+ }, [ref]);
return state;
};
diff --git a/src/useScroll.ts b/src/useScroll.ts
index a98a7c3f..caf78f49 100644
--- a/src/useScroll.ts
+++ b/src/useScroll.ts
@@ -48,7 +48,7 @@ const useScroll = (ref: RefObject): State => {
ref.current.removeEventListener('scroll', handler);
}
};
- }, [ref.current]);
+ }, [ref]);
return state;
};
diff --git a/src/useScrolling.ts b/src/useScrolling.ts
index 01dd1174..c95ae6c2 100644
--- a/src/useScrolling.ts
+++ b/src/useScrolling.ts
@@ -25,7 +25,7 @@ const useScrolling = (ref: RefObject): boolean => {
};
}
return () => {};
- }, [ref.current]);
+ }, [ref]);
return scrolling;
};
diff --git a/src/useStateValidator.ts b/src/useStateValidator.ts
new file mode 100644
index 00000000..cf9070f0
--- /dev/null
+++ b/src/useStateValidator.ts
@@ -0,0 +1,36 @@
+import { Dispatch, SetStateAction, useCallback, useEffect, useRef, useState } from 'react';
+
+export type ValidityState = [boolean | undefined, ...any[]];
+export type DispatchValidity = Dispatch>;
+
+export type Validator =
+ | {
+ (state?: S): V;
+ (state?: S, dispatch?: DispatchValidity): void;
+ }
+ | Function;
+
+export type UseValidatorReturn = [V, () => void];
+
+export default function useStateValidator(
+ state: S,
+ validator: Validator,
+ initialValidity: V = [undefined] as V
+): UseValidatorReturn {
+ const validatorFn = useRef(validator);
+
+ const [validity, setValidity] = useState(initialValidity);
+ const validate = useCallback(() => {
+ if (validatorFn.current.length === 2) {
+ validatorFn.current(state, setValidity);
+ } else {
+ setValidity(validatorFn.current(state));
+ }
+ }, [state]);
+
+ useEffect(() => {
+ validate();
+ }, [state]);
+
+ return [validity, validate];
+}
diff --git a/yarn.lock b/yarn.lock
index eb5ede3e..47e22d64 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -42,12 +42,12 @@
integrity sha512-FuRhDRtsd6IptKpHXAa+4WPZYY2ZzgowkbLBecEDDSje1X/apG7jQM33or3NdOmjXBKWGOg4JmSiRfUfuTtHXw==
dependencies:
"@babel/code-frame" "^7.5.5"
- "@babel/generator" "^7.6.0"
- "@babel/helpers" "^7.6.0"
- "@babel/parser" "^7.6.0"
+ "@babel/generator" "^7.6.4"
+ "@babel/helpers" "^7.6.2"
+ "@babel/parser" "^7.6.4"
"@babel/template" "^7.6.0"
- "@babel/traverse" "^7.6.0"
- "@babel/types" "^7.6.0"
+ "@babel/traverse" "^7.6.3"
+ "@babel/types" "^7.6.3"
convert-source-map "^1.1.0"
debug "^4.1.0"
json5 "^2.1.0"
@@ -264,6 +264,21 @@
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.6.3.tgz#9eff8b9c3eeae16a74d8d4ff30da2bd0d6f0487e"
integrity sha512-sUZdXlva1dt2Vw2RqbMkmfoImubO0D0gaCrNngV6Hi0DA4x3o4mlrq0tbfY0dZEUIccH8I6wQ4qgEtwcpOR6Qg==
+"@babel/parser@^7.6.2":
+ version "7.6.2"
+ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.6.2.tgz#205e9c95e16ba3b8b96090677a67c9d6075b70a1"
+ integrity sha512-mdFqWrSPCmikBoaBYMuBulzTIKuXVPtEISFbRRVNwMWpCms/hmE2kRq0bblUHaNRKrjRlmVbx1sDHmjmRgD2Xg==
+
+"@babel/parser@^7.6.3":
+ version "7.6.3"
+ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.6.3.tgz#9eff8b9c3eeae16a74d8d4ff30da2bd0d6f0487e"
+ integrity sha512-sUZdXlva1dt2Vw2RqbMkmfoImubO0D0gaCrNngV6Hi0DA4x3o4mlrq0tbfY0dZEUIccH8I6wQ4qgEtwcpOR6Qg==
+
+"@babel/parser@^7.6.4":
+ version "7.6.4"
+ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.6.4.tgz#cb9b36a7482110282d5cb6dd424ec9262b473d81"
+ integrity sha512-D8RHPW5qd0Vbyo3qb+YjO5nvUVRTXFLQ/FsDxJU2Nqz4uB5EnUN0ZQSEYpvTIbRuttig1XbHWU5oMeQwQSAA+A==
+
"@babel/plugin-proposal-async-generator-functions@^7.2.0":
version "7.2.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz#b289b306669dce4ad20b0252889a15768c9d417e"
@@ -322,6 +337,14 @@
"@babel/helper-plugin-utils" "^7.0.0"
"@babel/plugin-syntax-object-rest-spread" "^7.2.0"
+"@babel/plugin-proposal-object-rest-spread@^7.6.2":
+ version "7.6.2"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.6.2.tgz#8ffccc8f3a6545e9f78988b6bf4fe881b88e8096"
+ integrity sha512-LDBXlmADCsMZV1Y9OQwMc0MyGZ8Ta/zlD9N67BfQT8uYwkRswiu2hU6nJKrjrt/58aH/vqfQlR/9yId/7A2gWw==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.0.0"
+ "@babel/plugin-syntax-object-rest-spread" "^7.2.0"
+
"@babel/plugin-proposal-optional-catch-binding@^7.2.0":
version "7.2.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz#135d81edb68a081e55e56ec48541ece8065c38f5"
@@ -339,6 +362,15 @@
"@babel/helper-regex" "^7.4.4"
regexpu-core "^4.5.4"
+"@babel/plugin-proposal-unicode-property-regex@^7.6.2":
+ version "7.6.2"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.6.2.tgz#05413762894f41bfe42b9a5e80919bd575dcc802"
+ integrity sha512-NxHETdmpeSCtiatMRYWVJo7266rrvAC3DTeG5exQBIH/fMIUK7ejDNznBbn3HQl/o9peymRRg7Yqkx6PdUXmMw==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.0.0"
+ "@babel/helper-regex" "^7.4.4"
+ regexpu-core "^4.6.0"
+
"@babel/plugin-syntax-async-generators@^7.2.0":
version "7.2.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz#69e1f0db34c6f5a0cf7e2b3323bf159a76c8cb7f"
@@ -491,6 +523,15 @@
"@babel/helper-regex" "^7.4.4"
regexpu-core "^4.5.4"
+"@babel/plugin-transform-dotall-regex@^7.6.2":
+ version "7.6.2"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.6.2.tgz#44abb948b88f0199a627024e1508acaf8dc9b2f9"
+ integrity sha512-KGKT9aqKV+9YMZSkowzYoYEiHqgaDhGmPNZlZxX6UeHC4z30nC1J9IrZuGqbYFB1jaIGdv91ujpze0exiVK8bA==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.0.0"
+ "@babel/helper-regex" "^7.4.4"
+ regexpu-core "^4.6.0"
+
"@babel/plugin-transform-duplicate-keys@^7.2.0", "@babel/plugin-transform-duplicate-keys@^7.5.0":
version "7.5.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.5.0.tgz#c5dbf5106bf84cdf691222c0974c12b1df931853"
@@ -695,6 +736,13 @@
dependencies:
"@babel/helper-plugin-utils" "^7.0.0"
+"@babel/plugin-transform-spread@^7.6.2":
+ version "7.6.2"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.6.2.tgz#fc77cf798b24b10c46e1b51b1b88c2bf661bb8dd"
+ integrity sha512-DpSvPFryKdK1x+EDJYCy28nmAaIMdxmhot62jAXF/o99iA33Zj2Lmcp3vDmz+MUh0LNYVPvfj5iC3feb3/+PFg==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.0.0"
+
"@babel/plugin-transform-sticky-regex@^7.2.0":
version "7.2.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz#a1e454b5995560a9c1e0d537dfc15061fd2687e1"
@@ -736,6 +784,15 @@
"@babel/helper-regex" "^7.4.4"
regexpu-core "^4.5.4"
+"@babel/plugin-transform-unicode-regex@^7.6.2":
+ version "7.6.2"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.6.2.tgz#b692aad888a7e8d8b1b214be6b9dc03d5031f698"
+ integrity sha512-orZI6cWlR3nk2YmYdb0gImrgCUwb5cBUwjf6Ks6dvNVvXERkwtJWOQaEOjPiu0Gu1Tq6Yq/hruCZZOOi9F34Dw==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.0.0"
+ "@babel/helper-regex" "^7.4.4"
+ regexpu-core "^4.6.0"
+
"@babel/preset-env@7.4.3":
version "7.4.3"
resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.4.3.tgz#e71e16e123dc0fbf65a52cbcbcefd072fbd02880"
@@ -800,9 +857,9 @@
"@babel/plugin-proposal-async-generator-functions" "^7.2.0"
"@babel/plugin-proposal-dynamic-import" "^7.5.0"
"@babel/plugin-proposal-json-strings" "^7.2.0"
- "@babel/plugin-proposal-object-rest-spread" "^7.5.5"
+ "@babel/plugin-proposal-object-rest-spread" "^7.6.2"
"@babel/plugin-proposal-optional-catch-binding" "^7.2.0"
- "@babel/plugin-proposal-unicode-property-regex" "^7.4.4"
+ "@babel/plugin-proposal-unicode-property-regex" "^7.6.2"
"@babel/plugin-syntax-async-generators" "^7.2.0"
"@babel/plugin-syntax-dynamic-import" "^7.2.0"
"@babel/plugin-syntax-json-strings" "^7.2.0"
@@ -811,11 +868,11 @@
"@babel/plugin-transform-arrow-functions" "^7.2.0"
"@babel/plugin-transform-async-to-generator" "^7.5.0"
"@babel/plugin-transform-block-scoped-functions" "^7.2.0"
- "@babel/plugin-transform-block-scoping" "^7.6.0"
+ "@babel/plugin-transform-block-scoping" "^7.6.3"
"@babel/plugin-transform-classes" "^7.5.5"
"@babel/plugin-transform-computed-properties" "^7.2.0"
"@babel/plugin-transform-destructuring" "^7.6.0"
- "@babel/plugin-transform-dotall-regex" "^7.4.4"
+ "@babel/plugin-transform-dotall-regex" "^7.6.2"
"@babel/plugin-transform-duplicate-keys" "^7.5.0"
"@babel/plugin-transform-exponentiation-operator" "^7.2.0"
"@babel/plugin-transform-for-of" "^7.4.4"
@@ -826,7 +883,7 @@
"@babel/plugin-transform-modules-commonjs" "^7.6.0"
"@babel/plugin-transform-modules-systemjs" "^7.5.0"
"@babel/plugin-transform-modules-umd" "^7.2.0"
- "@babel/plugin-transform-named-capturing-groups-regex" "^7.6.0"
+ "@babel/plugin-transform-named-capturing-groups-regex" "^7.6.3"
"@babel/plugin-transform-new-target" "^7.4.4"
"@babel/plugin-transform-object-super" "^7.5.5"
"@babel/plugin-transform-parameters" "^7.4.4"
@@ -834,12 +891,12 @@
"@babel/plugin-transform-regenerator" "^7.4.5"
"@babel/plugin-transform-reserved-words" "^7.2.0"
"@babel/plugin-transform-shorthand-properties" "^7.2.0"
- "@babel/plugin-transform-spread" "^7.2.0"
+ "@babel/plugin-transform-spread" "^7.6.2"
"@babel/plugin-transform-sticky-regex" "^7.2.0"
"@babel/plugin-transform-template-literals" "^7.4.4"
"@babel/plugin-transform-typeof-symbol" "^7.2.0"
- "@babel/plugin-transform-unicode-regex" "^7.4.4"
- "@babel/types" "^7.6.0"
+ "@babel/plugin-transform-unicode-regex" "^7.6.2"
+ "@babel/types" "^7.6.3"
browserslist "^4.6.0"
core-js-compat "^3.1.1"
invariant "^2.2.2"
@@ -865,6 +922,17 @@
"@babel/plugin-transform-react-jsx-self" "^7.0.0"
"@babel/plugin-transform-react-jsx-source" "^7.0.0"
+"@babel/preset-react@7.6.3":
+ version "7.6.3"
+ resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.6.3.tgz#d5242c828322520205ae4eda5d4f4f618964e2f6"
+ integrity sha512-07yQhmkZmRAfwREYIQgW0HEwMY9GBJVuPY4Q12UC72AbfaawuupVWa8zQs2tlL+yun45Nv/1KreII/0PLfEsgA==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.0.0"
+ "@babel/plugin-transform-react-display-name" "^7.0.0"
+ "@babel/plugin-transform-react-jsx" "^7.0.0"
+ "@babel/plugin-transform-react-jsx-self" "^7.0.0"
+ "@babel/plugin-transform-react-jsx-source" "^7.0.0"
+
"@babel/preset-typescript@7.3.3":
version "7.3.3"
resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.3.3.tgz#88669911053fa16b2b276ea2ede2ca603b3f307a"
@@ -935,6 +1003,15 @@
lodash "^4.17.13"
to-fast-properties "^2.0.0"
+"@babel/types@^7.6.3":
+ version "7.6.3"
+ resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.6.3.tgz#3f07d96f854f98e2fbd45c64b0cb942d11e8ba09"
+ integrity sha512-CqbcpTxMcpuQTMhjI37ZHVgjBkysg5icREQIEZ0eG1yCNwg3oy+5AaLiOKmjsCj6nqOsa6Hf0ObjRVwokb7srA==
+ dependencies:
+ esutils "^2.0.2"
+ lodash "^4.17.13"
+ to-fast-properties "^2.0.0"
+
"@cnakazawa/watch@^1.0.3":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.3.tgz#099139eaec7ebf07a27c1786a3ff64f39464d2ef"
@@ -1414,6 +1491,37 @@
into-stream "^4.0.0"
lodash "^4.17.4"
+"@shopify/async@^2.0.7":
+ version "2.0.7"
+ resolved "https://registry.yarnpkg.com/@shopify/async/-/async-2.0.7.tgz#944992bc1721df6c363b3f0f31be1dad0e75e929"
+ integrity sha512-wYGjqPhpna4ShYbUmlD2fPv5ZkjNlCZtU7huUU8/snnyPmdgL/Rn5M5FPP6Apr7/hU5RgqMj2tJFs37ORz/VaQ==
+
+"@shopify/decorators@^1.1.5":
+ version "1.1.5"
+ resolved "https://registry.yarnpkg.com/@shopify/decorators/-/decorators-1.1.5.tgz#b8da0bd5fffb04cde9730898fc04428f964cab1c"
+ integrity sha512-cFAwd7T5IjkPs1ef11dbA6cbJA+CtgCDanbalPlQdl5ItwDzqJXGpvbhbQXw7zPyNMLijrgrpQqltalqAy9wnQ==
+ dependencies:
+ "@shopify/function-enhancers" "^1.0.5"
+
+"@shopify/function-enhancers@^1.0.5":
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/@shopify/function-enhancers/-/function-enhancers-1.0.5.tgz#7c3e516e26ce7a9b63c263679bdcf5121d994a10"
+ integrity sha512-34ML8DX4RmmA9hXDlf2BAz4SA37unShZxoBRPz585a+FaEzNcMvw5NzLD+Ih9XrP/wrxTUcN+p6pazvoS+jB7w==
+
+"@shopify/jest-dom-mocks@2.8.2":
+ version "2.8.2"
+ resolved "https://registry.yarnpkg.com/@shopify/jest-dom-mocks/-/jest-dom-mocks-2.8.2.tgz#477c3159897807cc8d7797c33e8a79e787051779"
+ integrity sha512-4drt+S1cQ1ZSP1DaEHAj5XPPCiI2R8IIt+ZnH9h08Ngy8PjtjFFNHNcSJ6bKBmk7eO2c6+5UaJQzNcg56nt7gg==
+ dependencies:
+ "@shopify/async" "^2.0.7"
+ "@shopify/decorators" "^1.1.5"
+ "@types/fetch-mock" "^6.0.1"
+ "@types/lolex" "^2.1.3"
+ fetch-mock "^6.3.0"
+ lolex "^2.7.5"
+ promise "^8.0.3"
+ tslib "^1.9.3"
+
"@storybook/addon-actions@5.1.11":
version "5.1.11"
resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-5.1.11.tgz#ebc299b9dfe476b5c65eb5d148c4b064f682ca08"
@@ -1875,14 +1983,13 @@
"@svgr/plugin-svgo" "^4.3.1"
loader-utils "^1.2.3"
-"@testing-library/react-hooks@2.0.1":
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/@testing-library/react-hooks/-/react-hooks-2.0.1.tgz#1c3ec40882d0830df3078ddae0056fdf7366c81d"
- integrity sha512-MLTvWX7/csq/uQzP4WJntGz0QJDq6H4EzjV0VTL5YJE7KBZbaQ9DGT0IbtjuB33L4R4YKZ55rGZQ5eL+WiZtQA==
+"@testing-library/react-hooks@2.0.3":
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/@testing-library/react-hooks/-/react-hooks-2.0.3.tgz#305a6c76facb5fa1d185792b9eb11b1ca1b63fb7"
+ integrity sha512-adm+7b1gcysGka8VuYq/ObBrIBJTT9QmCEIqPpuxozWFfVDgxSbzBGc44ia/WYLGVt2dqFIOc6/DmAmu/pa0gQ==
dependencies:
"@babel/runtime" "^7.5.4"
- "@types/react" ">=16.9.0"
- "@types/react-test-renderer" ">=16.9.0"
+ "@types/testing-library__react-hooks" "^2.0.0"
"@types/babel__core@^7.1.0":
version "7.1.0"
@@ -1922,6 +2029,11 @@
resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7"
integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==
+"@types/fetch-mock@^6.0.1":
+ version "6.0.5"
+ resolved "https://registry.yarnpkg.com/@types/fetch-mock/-/fetch-mock-6.0.5.tgz#acbc6771d43d7ebc1f0a8b7e3d57147618f8eacb"
+ integrity sha512-rV8O2j/TIi0PtFCOlK55JnfKpE8Hm6PKFgrUZY/3FNHw4uBEMHnM+5ZickDO1duOyKxbpY3VES5T4NIwZXvodA==
+
"@types/glob@^7.1.1":
version "7.1.1"
resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575"
@@ -1963,6 +2075,11 @@
dependencies:
"@types/jest-diff" "*"
+"@types/lolex@^2.1.3":
+ version "2.1.3"
+ resolved "https://registry.yarnpkg.com/@types/lolex/-/lolex-2.1.3.tgz#793557c9b8ad319b4c8e4c6548b90893f4aa5f69"
+ integrity sha512-nEipOLYyZJ4RKHCg7tlR37ewFy91oggmip2MBzPdVQ8QhTFqjcRhE8R0t4tfpDnSlxGWHoEGJl0UCC4kYhqoiw==
+
"@types/minimatch@*":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
@@ -1988,7 +2105,7 @@
resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8"
integrity sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw==
-"@types/react-test-renderer@>=16.9.0":
+"@types/react-test-renderer@*":
version "16.9.0"
resolved "https://registry.yarnpkg.com/@types/react-test-renderer/-/react-test-renderer-16.9.0.tgz#d60f530ecf4c906721511603cca711b4fa830d41"
integrity sha512-bN5EyjtuTY35xX7N5j0KP1vg5MpUXHpFTX6tGsqkNOthjNvet4VQOYRxFh+NT5cDSJrATmAFK9NLeYZ4mp/o0Q==
@@ -2023,6 +2140,14 @@
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e"
integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==
+"@types/testing-library__react-hooks@^2.0.0":
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/@types/testing-library__react-hooks/-/testing-library__react-hooks-2.0.0.tgz#7b289d64945517ae8ba9cbcb0c5b282432aaeffa"
+ integrity sha512-YUVqXGCChJKEJ4aAnMXqPCq0NfPAFVsJeGIb2y/iiMjxwyu+45+vR+AHOwjJHHKEHeC0ZhOGrZ5gSEmaJe4tyQ==
+ dependencies:
+ "@types/react" "*"
+ "@types/react-test-renderer" "*"
+
"@types/yargs-parser@*":
version "13.0.0"
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-13.0.0.tgz#453743c5bbf9f1bed61d959baab5b06be029b2d0"
@@ -2560,7 +2685,7 @@ arrify@^1.0.1:
resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=
-asap@^2.0.0, asap@~2.0.3:
+asap@^2.0.0, asap@~2.0.3, asap@~2.0.6:
version "2.0.6"
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=
@@ -3020,6 +3145,15 @@ babel-plugin-transform-undefined-to-void@^6.9.4:
resolved "https://registry.yarnpkg.com/babel-plugin-transform-undefined-to-void/-/babel-plugin-transform-undefined-to-void-6.9.4.tgz#be241ca81404030678b748717322b89d0c8fe280"
integrity sha1-viQcqBQEAwZ4t0hxcyK4nQyP4oA=
+babel-polyfill@^6.26.0:
+ version "6.26.0"
+ resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.26.0.tgz#379937abc67d7895970adc621f284cd966cf2153"
+ integrity sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=
+ dependencies:
+ babel-runtime "^6.26.0"
+ core-js "^2.5.0"
+ regenerator-runtime "^0.10.5"
+
babel-preset-jest@^24.9.0:
version "24.9.0"
resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-24.9.0.tgz#192b521e2217fb1d1f67cf73f70c336650ad3cdc"
@@ -5347,6 +5481,15 @@ fbjs@^0.8.0, fbjs@^0.8.1:
setimmediate "^1.0.5"
ua-parser-js "^0.7.18"
+fetch-mock@^6.3.0:
+ version "6.5.2"
+ resolved "https://registry.yarnpkg.com/fetch-mock/-/fetch-mock-6.5.2.tgz#b3842b305c13ea0f81c85919cfaa7de387adfa3e"
+ integrity sha512-EIvbpCLBTYyDLu4HJiqD7wC8psDwTUaPaWXNKZbhNO/peUYKiNp5PkZGKRJtnTxaPQu71ivqafvjpM7aL+MofQ==
+ dependencies:
+ babel-polyfill "^6.26.0"
+ glob-to-regexp "^0.4.0"
+ path-to-regexp "^2.2.1"
+
figgy-pudding@^3.4.1, figgy-pudding@^3.5.1:
version "3.5.1"
resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790"
@@ -5554,10 +5697,10 @@ fork-ts-checker-webpack-plugin@1.1.1:
tapable "^1.0.0"
worker-rpc "^0.1.0"
-fork-ts-checker-webpack-plugin@1.5.0:
- version "1.5.0"
- resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-1.5.0.tgz#ce1d77190b44d81a761b10b6284a373795e41f0c"
- integrity sha512-zEhg7Hz+KhZlBhILYpXy+Beu96gwvkROWJiTXOCyOOMMrdBIRPvsBpBqgTI4jfJGrJXcqGwJR8zsBGDmzY0jsA==
+fork-ts-checker-webpack-plugin@1.5.1:
+ version "1.5.1"
+ resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-1.5.1.tgz#f82d078ba8911c7b2c70703ffb3cbe588b33fbaa"
+ integrity sha512-IbVh1Z46dmCXJMg6We8s9jYwCAzzSv2Tgj+G2Sg/8pFantHDBrAg/rQyPnmAWLS/djW7n4VEltoEglbtTvt0wQ==
dependencies:
babel-code-frame "^6.22.0"
chalk "^2.4.1"
@@ -5848,6 +5991,11 @@ glob-to-regexp@^0.3.0:
resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab"
integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=
+glob-to-regexp@^0.4.0:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e"
+ integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==
+
glob@^7.0.0, glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4:
version "7.1.4"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255"
@@ -6286,20 +6434,20 @@ humanize-url@^1.0.0:
normalize-url "^1.0.0"
strip-url-auth "^1.0.0"
-husky@3.0.5:
- version "3.0.5"
- resolved "https://registry.yarnpkg.com/husky/-/husky-3.0.5.tgz#d7db27c346645a8dc52df02aa534a377ad7925e0"
- integrity sha512-cKd09Jy9cDyNIvAdN2QQAP/oA21sle4FWXjIMDttailpLAYZuBE7WaPmhrkj+afS8Sj9isghAtFvWSQ0JiwOHg==
+husky@3.0.9:
+ version "3.0.9"
+ resolved "https://registry.yarnpkg.com/husky/-/husky-3.0.9.tgz#a2c3e9829bfd6b4957509a9500d2eef5dbfc8044"
+ integrity sha512-Yolhupm7le2/MqC1VYLk/cNmYxsSsqKkTyBhzQHhPK1jFnC89mmmNVuGtLNabjDI6Aj8UNIr0KpRNuBkiC4+sg==
dependencies:
chalk "^2.4.2"
+ ci-info "^2.0.0"
cosmiconfig "^5.2.1"
execa "^1.0.0"
get-stdin "^7.0.0"
- is-ci "^2.0.0"
opencollective-postinstall "^2.0.2"
pkg-dir "^4.2.0"
please-upgrade-node "^3.2.0"
- read-pkg "^5.1.1"
+ read-pkg "^5.2.0"
run-node "^1.0.0"
slash "^3.0.0"
@@ -7746,10 +7894,10 @@ lines-and-columns@^1.1.6:
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00"
integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=
-lint-staged@9.2.5:
- version "9.2.5"
- resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-9.2.5.tgz#5a3e1e0a539a403bd7f88542bc3d34ce52efdbb3"
- integrity sha512-d99gTBFMJ29159+9iRvaMEQstmNcPAbQbhHSYw6D/1FncvFdIj8lWHztaq3Uq+tbZPABHXQ/fyN7Rp1QwF8HIw==
+lint-staged@9.4.2:
+ version "9.4.2"
+ resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-9.4.2.tgz#14cb577a9512f520691f8b5aefce6a8f7ead6c04"
+ integrity sha512-OFyGokJSWTn2M6vngnlLXjaHhi8n83VIZZ5/1Z26SULRUWgR3ITWpAEQC9Pnm3MC/EpCxlwts/mQWDHNji2+zA==
dependencies:
chalk "^2.4.2"
commander "^2.20.0"
@@ -8003,6 +8151,11 @@ log-update@^2.3.0:
cli-cursor "^2.0.0"
wrap-ansi "^3.0.1"
+lolex@^2.7.5:
+ version "2.7.5"
+ resolved "https://registry.yarnpkg.com/lolex/-/lolex-2.7.5.tgz#113001d56bfc7e02d56e36291cc5c413d1aa0733"
+ integrity sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q==
+
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
@@ -9419,6 +9572,16 @@ parse-json@^4.0.0:
error-ex "^1.3.1"
json-parse-better-errors "^1.0.1"
+parse-json@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.0.0.tgz#73e5114c986d143efa3712d4ea24db9a4266f60f"
+ integrity sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==
+ dependencies:
+ "@babel/code-frame" "^7.0.0"
+ error-ex "^1.3.1"
+ json-parse-better-errors "^1.0.1"
+ lines-and-columns "^1.1.6"
+
parse5@4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608"
@@ -9479,6 +9642,11 @@ path-to-regexp@0.1.7:
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c"
integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=
+path-to-regexp@^2.2.1:
+ version "2.4.0"
+ resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-2.4.0.tgz#35ce7f333d5616f1c1e1bfe266c3aba2e5b2e704"
+ integrity sha512-G6zHoVqC6GGTQkZwF4lkuEyMbVOjoBKAEybQUypI1WTkqinCOrq2x6U2+phkJ1XsEMTy4LjtwPI7HW+NVrRR2w==
+
path-type@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f"
@@ -9799,6 +9967,13 @@ promise@^7.1.1:
dependencies:
asap "~2.0.3"
+promise@^8.0.3:
+ version "8.0.3"
+ resolved "https://registry.yarnpkg.com/promise/-/promise-8.0.3.tgz#f592e099c6cddc000d538ee7283bb190452b0bf6"
+ integrity sha512-HeRDUL1RJiLhyA0/grn+PTShlBAcLuh/1BJGtrvjwbvRDCTLLMEz9rOGCV+R3vHY4MixIuoMEd9Yq/XvsTPcjw==
+ dependencies:
+ asap "~2.0.6"
+
prompts@^2.0.1:
version "2.0.4"
resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.0.4.tgz#179f9d4db3128b9933aa35f93a800d8fce76a682"
@@ -10113,7 +10288,17 @@ react-docgen@^4.1.0:
node-dir "^0.1.10"
recast "^0.17.3"
-react-dom@16.9.0, react-dom@^16.8.3:
+react-dom@16.10.2:
+ version "16.10.2"
+ resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.10.2.tgz#4840bce5409176bc3a1f2bd8cb10b92db452fda6"
+ integrity sha512-kWGDcH3ItJK4+6Pl9DZB16BXYAZyrYQItU4OMy0jAkv5aNqc+mAKb4TpFtAteI6TJZu+9ZlNhaeNQSVQDHJzkw==
+ dependencies:
+ loose-envify "^1.1.0"
+ object-assign "^4.1.1"
+ prop-types "^15.6.2"
+ scheduler "^0.16.2"
+
+react-dom@^16.8.3:
version "16.9.0"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.9.0.tgz#5e65527a5e26f22ae3701131bcccaee9fb0d3962"
integrity sha512-YFT2rxO9hM70ewk9jq0y6sQk8cL02xm4+IzYBz75CQGlClQQ1Bxq0nhHF6OtSbit+AIahujJgb/CPRibFkMNJQ==
@@ -10195,6 +10380,11 @@ react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4, react-is@^16.9.0:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.10.2.tgz#984120fd4d16800e9a738208ab1fba422d23b5ab"
integrity sha512-INBT1QEgtcCCgvccr5/86CfD71fw9EPmDxgiJX4I2Ddr6ZsV6iFXsuby+qWJPtmNuMY0zByTsG4468P7nHuNWA==
+react-is@^16.8.6:
+ version "16.10.0"
+ resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.10.0.tgz#3d6a031e57fff73c3cfa0347feb3e8f40c5141e5"
+ integrity sha512-WRki2sBb7MTpYp7FtDEmSeGKX2vamYyq3rc9o7fKUG+/DHVyJu69NnvJsiSwwhh2Tt8XN40MQHkDBEXwyfxncQ==
+
react-lifecycles-compat@^3.0.2, react-lifecycles-compat@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
@@ -10263,15 +10453,15 @@ react-syntax-highlighter@^8.0.1:
prismjs "^1.8.4"
refractor "^2.4.1"
-react-test-renderer@16.9.0:
- version "16.9.0"
- resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.9.0.tgz#7ed657a374af47af88f66f33a3ef99c9610c8ae9"
- integrity sha512-R62stB73qZyhrJo7wmCW9jgl/07ai+YzvouvCXIJLBkRlRqLx4j9RqcLEAfNfU3OxTGucqR2Whmn3/Aad6L3hQ==
+react-test-renderer@16.10.2:
+ version "16.10.2"
+ resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.10.2.tgz#4d8492f8678c9b43b721a7d79ed0840fdae7c518"
+ integrity sha512-k9Qzyev6cTIcIfrhgrFlYQAFxh5EEDO6ALNqYqmKsWVA7Q/rUMTay5nD3nthi6COmYsd4ghVYyi8U86aoeMqYQ==
dependencies:
object-assign "^4.1.1"
prop-types "^15.6.2"
- react-is "^16.9.0"
- scheduler "^0.15.0"
+ react-is "^16.8.6"
+ scheduler "^0.16.2"
react-textarea-autosize@^7.1.0:
version "7.1.0"
@@ -10296,7 +10486,16 @@ react-wait@^0.3.0:
resolved "https://registry.yarnpkg.com/react-wait/-/react-wait-0.3.0.tgz#0cdd4d919012451a5bc3ab0a16d00c6fd9a8c10b"
integrity sha512-kB5x/kMKWcn0uVr9gBdNz21/oGbQwEQnF3P9p6E9yLfJ9DRcKS0fagbgYMFI0YFOoyKDj+2q6Rwax0kTYJF37g==
-react@16.9.0, react@^16.8.3:
+react@16.10.2:
+ version "16.10.2"
+ resolved "https://registry.yarnpkg.com/react/-/react-16.10.2.tgz#a5ede5cdd5c536f745173c8da47bda64797a4cf0"
+ integrity sha512-MFVIq0DpIhrHFyqLU0S3+4dIcBhhOvBE8bJ/5kHPVOVaGdo0KuiQzpcjCPsf585WvhypqtrMILyoE2th6dT+Lw==
+ dependencies:
+ loose-envify "^1.1.0"
+ object-assign "^4.1.1"
+ prop-types "^15.6.2"
+
+react@^16.8.3:
version "16.9.0"
resolved "https://registry.yarnpkg.com/react/-/react-16.9.0.tgz#40ba2f9af13bc1a38d75dbf2f4359a5185c4f7aa"
integrity sha512-+7LQnFBwkiw+BobzOF6N//BdoNw0ouwmSJTEm9cglOOmsg/TMiFHZLe2sEoN5M7LgJTj9oHH0gxklfnQe66S1w==
@@ -10400,6 +10599,16 @@ read-pkg@^5.0.0, read-pkg@^5.1.1:
parse-json "^4.0.0"
type-fest "^0.4.1"
+read-pkg@^5.2.0:
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc"
+ integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==
+ dependencies:
+ "@types/normalize-package-data" "^2.4.0"
+ normalize-package-data "^2.5.0"
+ parse-json "^5.0.0"
+ type-fest "^0.6.0"
+
read@1, read@~1.0.1, read@~1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4"
@@ -10559,11 +10768,23 @@ regenerate-unicode-properties@^8.0.2, regenerate-unicode-properties@^8.1.0:
dependencies:
regenerate "^1.4.0"
+regenerate-unicode-properties@^8.1.0:
+ version "8.1.0"
+ resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz#ef51e0f0ea4ad424b77bf7cb41f3e015c70a3f0e"
+ integrity sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA==
+ dependencies:
+ regenerate "^1.4.0"
+
regenerate@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11"
integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==
+regenerator-runtime@^0.10.5:
+ version "0.10.5"
+ resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658"
+ integrity sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=
+
regenerator-runtime@^0.11.0:
version "0.11.1"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"
@@ -10618,6 +10839,18 @@ regexpu-core@^4.5.4, regexpu-core@^4.6.0:
unicode-match-property-ecmascript "^1.0.4"
unicode-match-property-value-ecmascript "^1.1.0"
+regexpu-core@^4.6.0:
+ version "4.6.0"
+ resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.6.0.tgz#2037c18b327cfce8a6fea2a4ec441f2432afb8b6"
+ integrity sha512-YlVaefl8P5BnFYOITTNzDvan1ulLOiXJzCNZxduTIosN17b87h3bvG9yHMoHaRuo88H4mQ06Aodj5VtYGGGiTg==
+ dependencies:
+ regenerate "^1.4.0"
+ regenerate-unicode-properties "^8.1.0"
+ regjsgen "^0.5.0"
+ regjsparser "^0.6.0"
+ unicode-match-property-ecmascript "^1.0.4"
+ unicode-match-property-value-ecmascript "^1.1.0"
+
registry-auth-token@^3.0.1:
version "3.3.2"
resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.3.2.tgz#851fd49038eecb586911115af845260eec983f20"
@@ -10940,6 +11173,14 @@ scheduler@^0.15.0:
loose-envify "^1.1.0"
object-assign "^4.1.1"
+scheduler@^0.16.2:
+ version "0.16.2"
+ resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.16.2.tgz#f74cd9d33eff6fc554edfb79864868e4819132c1"
+ integrity sha512-BqYVWqwz6s1wZMhjFvLfVR5WXP7ZY32M/wYPo04CcuPM7XZEbV2TBNW7Z0UkguPTl0dWMA59VbNXxK6q+pHItg==
+ dependencies:
+ loose-envify "^1.1.0"
+ object-assign "^4.1.1"
+
schema-utils@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770"
@@ -12119,10 +12360,10 @@ ts-easing@^0.2.0:
resolved "https://registry.yarnpkg.com/ts-easing/-/ts-easing-0.2.0.tgz#c8a8a35025105566588d87dbda05dd7fbfa5a4ec"
integrity sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ==
-ts-loader@6.1.0:
- version "6.1.0"
- resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-6.1.0.tgz#999cb0a7644f9c7c6c0901802dce50ceb0a76e5b"
- integrity sha512-7JedeOu2rsYHQDEr2fwmMozABwbQTZXEaEMZPSIWG7gpzRefOLJCqwdazcegHtyaxp04PeEgs/b0m08WMpnIzQ==
+ts-loader@6.2.0:
+ version "6.2.0"
+ resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-6.2.0.tgz#52d3993ecbc5474c1513242388e1049da0fce880"
+ integrity sha512-Da8h3fD+HiZ9GvZJydqzk3mTC9nuOKYlJcpuk+Zv6Y1DPaMvBL+56GRzZFypx2cWrZFMsQr869+Ua2slGoLxvQ==
dependencies:
chalk "^2.3.0"
enhanced-resolve "^4.0.0"
@@ -12130,10 +12371,10 @@ ts-loader@6.1.0:
micromatch "^4.0.0"
semver "^6.0.0"
-ts-node@8.3.0:
- version "8.3.0"
- resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.3.0.tgz#e4059618411371924a1fb5f3b125915f324efb57"
- integrity sha512-dyNS/RqyVTDcmNM4NIBAeDMpsAdaQ+ojdf0GOLqE6nwJOgzEkdRNzJywhDfwnuvB10oa6NLVG1rUJQCpRN7qoQ==
+ts-node@8.4.1:
+ version "8.4.1"
+ resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.4.1.tgz#270b0dba16e8723c9fa4f9b4775d3810fd994b4f"
+ integrity sha512-5LpRN+mTiCs7lI5EtbXmF/HfMeCjzt7DH9CZwtkr6SywStrNQC723wG+aOWFiLNn7zT3kD/RnFqi3ZUfr4l5Qw==
dependencies:
arg "^4.1.0"
diff "^4.0.1"
@@ -12179,10 +12420,10 @@ tslint-plugin-prettier@2.0.1:
lines-and-columns "^1.1.6"
tslib "^1.7.1"
-tslint-react@4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/tslint-react/-/tslint-react-4.0.0.tgz#b4bb4c01c32448cb14d23f143a2f5e4989bb961e"
- integrity sha512-9fNE0fm9zNDx1+b6hgy8rgDN2WsQLRiIrn3+fbqm0tazBVF6jiaCFAITxmU+WSFWYE03Xhp1joCircXOe1WVAQ==
+tslint-react@4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/tslint-react/-/tslint-react-4.1.0.tgz#7153b724a8cfbea52423d0ffa469e8eba3bcc834"
+ integrity sha512-Y7CbFn09X7Mpg6rc7t/WPbmjx9xPI8p1RsQyiGCLWgDR6sh3+IBSlT+bEkc0PSZcWwClOkqq2wPsID8Vep6szQ==
dependencies:
tsutils "^3.9.1"
@@ -12258,6 +12499,11 @@ type-fest@^0.5.0:
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.5.2.tgz#d6ef42a0356c6cd45f49485c3b6281fc148e48a2"
integrity sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw==
+type-fest@^0.6.0:
+ version "0.6.0"
+ resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b"
+ integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==
+
type-is@~1.6.17, type-is@~1.6.18:
version "1.6.18"
resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131"
@@ -12949,3 +13195,4 @@ yn@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/yn/-/yn-3.0.0.tgz#0073c6b56e92aed652fbdfd62431f2d6b9a7a091"
integrity sha512-+Wo/p5VRfxUgBUGy2j/6KX2mj9AYJWOHuhMjMcbBFc3y54o9/4buK1ksBvuiK01C3kby8DH9lSmJdSxw+4G/2Q==
+