Merge branch 'master' into master

This commit is contained in:
Anton Zinovyev 2019-08-03 02:34:02 +03:00 committed by GitHub
commit da3628e201
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
35 changed files with 1394 additions and 477 deletions

View File

@ -1,3 +1,19 @@
# [10.4.0](https://github.com/streamich/react-use/compare/v10.3.1...v10.4.0) (2019-08-02)
### Features
* add useMountedState hook ([9081b99](https://github.com/streamich/react-use/commit/9081b99))
## [10.3.1](https://github.com/streamich/react-use/compare/v10.3.0...v10.3.1) (2019-08-02)
### Bug Fixes
* **storybook:** fix useKeyboardJs import path ([b7481f6](https://github.com/streamich/react-use/commit/b7481f6))
* **useKeyboardJs:** fix argument type error ([8c820ce](https://github.com/streamich/react-use/commit/8c820ce))
* allow string list in useKeyboardJs hook ([aecbd0b](https://github.com/streamich/react-use/commit/aecbd0b))
# [10.3.0](https://github.com/streamich/react-use/compare/v10.2.0...v10.3.0) (2019-07-26)

View File

@ -102,12 +102,12 @@
- [`useTitle`](./docs/useTitle.md) — sets title of the page.
- [`usePermission`](./docs/usePermission.md) — query permission status for browser APIs.
<br/>
<br/>
<br/>
- [**Lifecycles**](./docs/Lifecycles.md)
- [`useEffectOnce`](./docs/useEffectOnce.md) &mdash; a modified [`useEffect`](https://reactjs.org/docs/hooks-reference.html#useeffect) hook that only runs once.
- [`useEvent`](./docs/useEvent.md) &mdash; subscribe to events.
- [`useLifecycles`](./docs/useLifecycles.md) &mdash; calls `mount` and `unmount` callbacks.
- [`useRefMounted`](./docs/useRefMounted.md) &mdash; tracks if component is mounted.
- [`useMountedState`](./docs/useMountedState.md) and [`useRefMounted`](./docs/useRefMounted.md) &mdash; track if component is mounted.
- [`usePromise`](./docs/usePromise.md) &mdash; resolves promise only while component is mounted.
- [`useLogger`](./docs/useLogger.md) &mdash; logs in console as component goes through life-cycles.
- [`useMount`](./docs/useMount.md) &mdash; calls `mount` callbacks.

View File

@ -37,5 +37,5 @@ yarn add keyboardjs
## Reference
```js
useKeyboardJs(combination: string): [isPressed: boolean, event?: KeyboardEvent]
useKeyboardJs(combination: string | string[]): [isPressed: boolean, event?: KeyboardEvent]
```

25
docs/useMountedState.md Normal file
View File

@ -0,0 +1,25 @@
# `useMountedState`
Lifecycle hook providing ability to check component's mount state.
Gives a function that will return `true` if component mounted and `false` otherwise.
## Usage
```jsx
import * as React from 'react';
import {useMountedState} from 'react-use';
const Demo = () => {
const isMounted = useMountedState();
React.useEffect(() => {
setTimeout(() => {
if (isMounted()) {
// ...
} else {
// ...
}
}, 1000);
});
};
```

View File

@ -1,6 +1,6 @@
{
"name": "react-use",
"version": "10.3.0",
"version": "10.4.0",
"description": "Collection of React Hooks",
"main": "lib/index.js",
"module": "esm/index.js",
@ -24,7 +24,7 @@
"clean": "rimraf lib storybook-static esm",
"storybook": "start-storybook -p 6008",
"storybook:build": "build-storybook",
"storybook:upload": "gh-pages -d storybook-static",
"storybook:upload": "gh-pages -d storybook-static --git \"$(which git)\"",
"storybook:clean": "rimraf storybook-static",
"release": "semantic-release"
},
@ -67,34 +67,35 @@
"@semantic-release/changelog": "3.0.4",
"@semantic-release/git": "7.0.16",
"@semantic-release/npm": "5.1.13",
"@storybook/addon-actions": "5.1.9",
"@storybook/addon-knobs": "5.1.9",
"@storybook/addon-notes": "5.1.9",
"@storybook/addon-options": "5.1.9",
"@storybook/react": "5.1.9",
"@types/jest": "24.0.15",
"@storybook/addon-actions": "5.1.10",
"@storybook/addon-knobs": "5.1.10",
"@storybook/addon-notes": "5.1.10",
"@storybook/addon-options": "5.1.10",
"@storybook/react": "5.1.10",
"@testing-library/react-hooks": "^1.1.0",
"@types/jest": "24.0.16",
"@types/react": "16.8.23",
"babel-core": "6.26.3",
"babel-loader": "8.0.6",
"babel-plugin-dynamic-import-node": "2.3.0",
"fork-ts-checker-webpack-plugin": "1.4.3",
"gh-pages": "2.0.1",
"husky": "3.0.1",
"gh-pages": "2.1.0",
"husky": "3.0.2",
"jest": "24.8.0",
"keyboardjs": "2.5.1",
"lint-staged": "9.2.1",
"markdown-loader": "5.0.0",
"markdown-loader": "5.1.0",
"prettier": "1.17.1",
"react": "16.8.6",
"react-dom": "16.8.6",
"react-hooks-testing-library": "0.4.1",
"react-spring": "8.0.27",
"react-test-renderer": "^16.8.6",
"rebound": "0.1.0",
"redux-logger": "3.0.6",
"redux-thunk": "2.3.0",
"rimraf": "2.6.3",
"rxjs": "6.5.2",
"semantic-release": "15.13.18",
"semantic-release": "15.13.19",
"ts-loader": "6.0.4",
"ts-node": "8.3.0",
"tslint": "5.18.0",

View File

@ -1,7 +1,7 @@
import { text, withKnobs } from '@storybook/addon-knobs';
import { storiesOf } from '@storybook/react';
import * as React from 'react';
import { useKeyboardJs } from '..';
import useKeyboardJs from '../useKeyboardJs';
import { CenterStory } from './util/CenterStory';
import ShowDocs from './util/ShowDocs';

View File

@ -0,0 +1,17 @@
import { storiesOf } from '@storybook/react';
import * as React from 'react';
import { useMountedState } from '..';
import ShowDocs from './util/ShowDocs';
const Demo = () => {
const isMounted = useMountedState();
const [, updateState] = React.useState();
requestAnimationFrame(updateState);
return <div>This component is {isMounted() ? 'MOUNTED' : 'NOT MOUNTED'}</div>;
};
storiesOf('Lifecycle|useMountedState', module)
.add('Docs', () => <ShowDocs md={require('../../docs/useMountedState.md')} />)
.add('Demo', () => <Demo />);

View File

@ -0,0 +1,45 @@
import { renderHook } from '@testing-library/react-hooks';
import createMemo from '../createMemo';
const getDouble = jest.fn((n: number): number => n * 2);
it('should init memo hook', () => {
const useMemoGetDouble = createMemo(getDouble);
expect(useMemoGetDouble).toBeInstanceOf(Function);
});
describe('when using created memo hook', () => {
let useMemoGetDouble;
beforeEach(() => {
useMemoGetDouble = createMemo(getDouble);
});
it.each([[1], [3], [5]])('should return same result as original function for argument %d', (val: number) => {
const { result } = renderHook(() => useMemoGetDouble(val));
expect(result.current).toBe(getDouble(val));
});
it('should NOT call original function for same arguments', () => {
let initialValue = 5;
expect(getDouble).not.toHaveBeenCalled();
// it's called first time calculating for argument 5
const { rerender } = renderHook(() => useMemoGetDouble(initialValue));
expect(getDouble).toHaveBeenCalled();
getDouble.mockClear();
// it's NOT called second time calculating for argument 5
rerender();
expect(getDouble).not.toHaveBeenCalled();
getDouble.mockClear();
// it's called again calculating for different argument
initialValue = 7;
rerender();
expect(getDouble).toHaveBeenCalled();
});
});

View File

@ -0,0 +1,112 @@
import { act, renderHook } from '@testing-library/react-hooks';
import createReducer from '../createReducer';
import logger from 'redux-logger';
import thunk from 'redux-thunk';
it('should init reducer hook function', () => {
const useSomeReducer = createReducer();
expect(useSomeReducer).toBeInstanceOf(Function);
});
/**
* This test suite implements the special demo in storybook that creates a
* reducer with thunk and logger for using a simple counter
*/
describe('when using created reducer hook', () => {
const initialCount = 1;
let originalLog;
let originalGroup;
const mockLog = jest.fn();
const mockGroup = jest.fn();
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
case 'reset':
return { count: action.payload };
default:
throw new Error();
}
}
// Action creator to increment count, wait a second and then reset
const addAndReset = () => {
return dispatch => {
dispatch({ type: 'increment' });
setTimeout(() => {
dispatch({ type: 'reset', payload: initialCount });
}, 1000);
};
};
const setUp = () => {
const useThunkReducer = createReducer(thunk, logger);
return renderHook(() => useThunkReducer(reducer, { count: initialCount }));
};
beforeAll(() => {
originalLog = console.log;
originalGroup = console.group;
console.log = mockLog;
console.group = mockGroup;
});
beforeEach(() => {
jest.useFakeTimers();
});
afterAll(() => {
console.log = originalLog;
console.group = originalGroup;
});
it('should init state and dispatcher', () => {
const { result } = setUp();
const [state, dispatch] = result.current;
expect(state).toEqual({ count: 1 });
expect(dispatch).toBeInstanceOf(Function);
});
it.each`
actionType | expectedCount | payload
${'increment'} | ${2} | ${undefined}
${'decrement'} | ${0} | ${undefined}
${'reset'} | ${1} | ${1}
`('should handle "$actionType" action', ({ actionType, expectedCount, payload }) => {
const { result } = setUp();
const [, dispatch] = result.current;
expect(mockLog).not.toHaveBeenCalled();
act(() => {
dispatch({ type: actionType, payload });
});
expect(result.current[0]).toEqual({ count: expectedCount });
expect(mockLog).toHaveBeenCalled();
});
it('should handle async action with several middlewares', () => {
const { result } = setUp();
const [, dispatch] = result.current;
expect(mockLog).not.toHaveBeenCalled();
act(() => {
dispatch(addAndReset());
});
expect(result.current[0]).toEqual({ count: 2 });
expect(mockLog).toHaveBeenCalled();
// fast-forward until all timers have been executed
act(() => {
jest.runAllTimers();
});
expect(result.current[0]).toEqual({ count: 1 });
});
});

View File

@ -1,9 +1,7 @@
import { renderHook } from '@testing-library/react-hooks';
import { useCallback } from 'react';
import { cleanup, renderHook } from 'react-hooks-testing-library';
import useAsync from '../useAsync';
afterEach(cleanup);
// NOTE: these tests cause console errors.
// maybe we should test in a real environment instead
// of a fake one?
@ -17,7 +15,7 @@ describe('useAsync', () => {
let callCount = 0;
const resolver = async () => {
return new Promise((resolve, reject) => {
return new Promise(resolve => {
callCount++;
const wait = setTimeout(() => {
@ -58,7 +56,7 @@ describe('useAsync', () => {
let callCount = 0;
const rejection = async () => {
return new Promise((resolve, reject) => {
return new Promise((_, reject) => {
callCount++;
const wait = setTimeout(() => {

View File

@ -5,11 +5,9 @@
// does not automatically invoke the function
// and it can take arguments.
import { cleanup, renderHook } from 'react-hooks-testing-library';
import { renderHook } from '@testing-library/react-hooks';
import useAsyncFn, { AsyncState } from '../useAsyncFn';
afterEach(cleanup);
type AdderFn = (a: number, b: number) => Promise<number>;
describe('useAsyncFn', () => {

View File

@ -0,0 +1,6 @@
import useBoolean from '../useBoolean';
import useToggle from '../useToggle';
it('should be an alias for useToggle ', () => {
expect(useBoolean).toBe(useToggle);
});

View File

@ -0,0 +1,128 @@
import { act, renderHook } from '@testing-library/react-hooks';
import useCounter from '../useCounter';
const setUp = (initialValue?: number) => renderHook(() => useCounter(initialValue));
it('should init counter and utils', () => {
const { result } = setUp(5);
expect(result.current[0]).toBe(5);
expect(result.current[1]).toStrictEqual({
inc: expect.any(Function),
dec: expect.any(Function),
get: expect.any(Function),
set: expect.any(Function),
reset: expect.any(Function),
});
});
it('should init counter to 0 if not initial value received', () => {
const { result } = setUp();
expect(result.current[0]).toBe(0);
});
it('should init counter to negative number', () => {
const { result } = setUp(-2);
expect(result.current[0]).toBe(-2);
});
it('should get current counter', () => {
const { result } = setUp(5);
const { get } = result.current[1];
expect(get()).toBe(5);
});
it('should increment by 1 if not value received', () => {
const { result } = setUp(5);
const { get, inc } = result.current[1];
act(() => inc());
expect(result.current[0]).toBe(6);
expect(get()).toBe(6);
});
it('should increment by value received', () => {
const { result } = setUp(5);
const { get, inc } = result.current[1];
act(() => inc(9));
expect(result.current[0]).toBe(14);
expect(get()).toBe(14);
});
it('should decrement by 1 if not value received', () => {
const { result } = setUp(5);
const { get, dec } = result.current[1];
act(() => dec());
expect(result.current[0]).toBe(4);
expect(get()).toBe(4);
});
it('should decrement by value received', () => {
const { result } = setUp(5);
const { get, dec } = result.current[1];
act(() => dec(9));
expect(result.current[0]).toBe(-4);
expect(get()).toBe(-4);
});
it('should set to value received', () => {
const { result } = setUp(5);
const { get, set } = result.current[1];
act(() => set(17));
expect(result.current[0]).toBe(17);
expect(get()).toBe(17);
});
it('should reset to original value', () => {
const { result } = setUp(5);
const { get, set, reset } = result.current[1];
// set different value than initial one...
act(() => set(17));
expect(result.current[0]).toBe(17);
// ... and reset it to initial one
act(() => reset());
expect(result.current[0]).toBe(5);
expect(get()).toBe(5);
});
it('should reset and set new original value', () => {
const { result } = setUp(5);
const { get, set, reset } = result.current[1];
// set different value than initial one...
act(() => set(17));
expect(result.current[0]).toBe(17);
// ... now reset and set it to different than initial one...
act(() => reset(8));
expect(result.current[0]).toBe(8);
// ... and set different value than initial one again...
act(() => set(32));
expect(result.current[0]).toBe(32);
// ... and reset it to new initial value
act(() => reset());
expect(result.current[0]).toBe(8);
expect(get()).toBe(8);
});
it.todo('should log an error if initial value is other than a number');
it.todo('should log an error if increment value is other than a number');
it.todo('should log an error if increment value is a negative number');
it.todo('should log an error if decrement value is other than a number');
it.todo('should log an error if decrement value is a negative number');

View File

@ -0,0 +1,61 @@
import { act, renderHook } from '@testing-library/react-hooks';
import useDefault from '../useDefault';
const setUp = (defaultValue: any, initialValue: any) => renderHook(() => useDefault(defaultValue, initialValue));
describe.each`
valueType | defaultValue | initialValue | anotherValue
${'number'} | ${0} | ${5} | ${77}
${'object'} | ${{}} | ${{ name: 'John Doe' }} | ${{ name: 'Solid Snake' }}
${'boolean'} | ${false} | ${false} | ${true}
${'string'} | ${''} | ${'foo'} | ${'bar'}
`('when value type is $valueType', ({ defaultValue, initialValue, anotherValue }) => {
it('should init state with initial value', () => {
const { result } = setUp(defaultValue, initialValue);
const [value, setValue] = result.current;
expect(value).toBe(initialValue);
expect(setValue).toBeInstanceOf(Function);
});
it('should set state to another value', () => {
const { result } = setUp(defaultValue, initialValue);
const [, setValue] = result.current;
act(() => setValue(anotherValue));
expect(result.current[0]).toBe(anotherValue);
});
it('should return default value if state set to null', () => {
const { result } = setUp(defaultValue, initialValue);
const [, setValue] = result.current;
act(() => setValue(null));
expect(result.current[0]).toBe(defaultValue);
});
it('should return default value if state set to undefined', () => {
const { result } = setUp(defaultValue, initialValue);
const [, setValue] = result.current;
act(() => setValue(undefined));
expect(result.current[0]).toBe(defaultValue);
});
it('should handle state properly after being set to nil and then to another value', () => {
const { result } = setUp(defaultValue, initialValue);
const [, setValue] = result.current;
act(() => setValue(undefined));
expect(result.current[0]).toBe(defaultValue);
act(() => setValue(null));
expect(result.current[0]).toBe(defaultValue);
act(() => setValue(anotherValue));
expect(result.current[0]).toBe(anotherValue);
});
});

View File

@ -1,40 +0,0 @@
import { act, cleanup, renderHook } from 'react-hooks-testing-library';
import useDefault from '../useDefault';
afterEach(cleanup);
describe('useDefault', () => {
test('should be defined', () => {
expect(useDefault).toBeDefined();
});
const hook = renderHook(() => useDefault({ name: 'Marshall' }, { name: '' }));
test('should return initial state on initial render', () => {
expect(hook.result.current[0].name).toBe('');
});
test('should update state with correct value', () => {
hook.rerender();
act(() => {
hook.result.current[1]({ name: 'Mathers' });
});
expect(hook.result.current[0].name).toBe('Mathers');
});
test('should return the default value when updated state is nil', () => {
hook.rerender();
act(() => {
hook.result.current[1](null);
});
expect(hook.result.current[0].name).toBe('Marshall');
act(() => {
hook.result.current[1](undefined);
});
expect(hook.result.current[0].name).toBe('Marshall');
});
});

View File

@ -0,0 +1,64 @@
import { act, renderHook } from '@testing-library/react-hooks';
import useGetSet from '../useGetSet';
const setUp = (initialValue: any) => renderHook(() => useGetSet(initialValue));
beforeEach(() => {
jest.useFakeTimers();
});
it('should init getter and setter', () => {
const { result } = setUp('foo');
const [get, set] = result.current;
expect(get).toBeInstanceOf(Function);
expect(set).toBeInstanceOf(Function);
});
it('should get current value', () => {
const { result } = setUp('foo');
const [get] = result.current;
const currentValue = get();
expect(currentValue).toBe('foo');
});
it('should set new value', () => {
const { result } = setUp('foo');
const [get, set] = result.current;
act(() => set('bar'));
const currentValue = get();
expect(currentValue).toBe('bar');
});
/**
* This test implements the special demo in storybook that increments a number
* after 1 second on each click.
*/
it('should get and set expected values when used in nested functions', () => {
const onClick = jest.fn(() => {
setTimeout(() => {
set(get() + 1);
}, 1000);
});
const { result } = setUp(0);
const [get, set] = result.current;
// simulate 3 clicks
onClick();
onClick();
onClick();
// fast-forward until all timers have been executed
act(() => {
jest.runAllTimers();
});
const currentValue = get();
expect(currentValue).toBe(3);
expect(onClick).toHaveBeenCalledTimes(3);
});

View File

@ -0,0 +1,136 @@
import { act, renderHook } from '@testing-library/react-hooks';
import useGetSetState from '../useGetSetState';
const originalConsoleError = console.error;
const mockConsoleError = jest.fn();
const setUp = (initialState: any) => renderHook(() => useGetSetState(initialState));
beforeAll(() => {
console.error = mockConsoleError;
});
afterAll(() => {
console.error = originalConsoleError;
});
beforeEach(() => {
jest.useFakeTimers();
});
it('should init getter and setter', () => {
const { result } = setUp({ foo: 'initialValue' });
const [get, set] = result.current;
expect(get).toBeInstanceOf(Function);
expect(set).toBeInstanceOf(Function);
});
it('should log an error if init with something different than an object', () => {
expect(mockConsoleError).not.toHaveBeenCalled();
setUp('not an object');
expect(mockConsoleError).toHaveBeenCalledTimes(1);
expect(mockConsoleError).toHaveBeenCalledWith('useGetSetState initial state must be an object.');
});
it('should get current state', () => {
const { result } = setUp({ foo: 'a', bar: 'z' });
const [get] = result.current;
const currentState = get();
expect(currentState).toEqual({ foo: 'a', bar: 'z' });
});
it('should set new state by applying patch with existing keys', () => {
const { result } = setUp({ foo: 'a', bar: 'z' });
const [get, set] = result.current;
act(() => set({ bar: 'y' }));
const currentState = get();
expect(currentState).toEqual({ foo: 'a', bar: 'y' });
});
it('should set new state by applying patch with new keys', () => {
const { result } = setUp({ foo: 'a', bar: 'z' });
const [get, set] = result.current;
act(() => set({ qux: 'f' }));
const currentState = get();
expect(currentState).toEqual({ foo: 'a', bar: 'z', qux: 'f' });
});
it('should set new state by applying patch with both new and old keys', () => {
const { result } = setUp({ foo: 'a', bar: 'z' });
const [get, set] = result.current;
act(() => set({ bar: 'y', qux: 'f' }));
const currentState = get();
expect(currentState).toEqual({ foo: 'a', bar: 'y', qux: 'f' });
});
it('should NOT set new state if empty patch received', () => {
const { result } = setUp({ foo: 'a', bar: 'z' });
const [get, set] = result.current;
act(() => set({}));
const currentState = get();
expect(currentState).toEqual({ foo: 'a', bar: 'z' });
});
it('should NOT set new state if no patch received', () => {
const { result } = setUp({ foo: 'a', bar: 'z' });
const [get, set] = result.current;
// @ts-ignore
act(() => set());
const currentState = get();
expect(currentState).toEqual({ foo: 'a', bar: 'z' });
});
it('should log an error if set with a patch different than an object', () => {
const { result } = setUp({ foo: 'a', bar: 'z' });
const [, set] = result.current;
expect(mockConsoleError).not.toHaveBeenCalled();
// @ts-ignore
act(() => set('not an object'));
expect(mockConsoleError).toHaveBeenCalledTimes(1);
expect(mockConsoleError).toHaveBeenCalledWith('useGetSetState setter patch must be an object.');
});
/**
* This test is equivalent to demo one for `useGetSet` hook.
*/
it('should get and set expected state when used in nested functions', () => {
const onClick = jest.fn(() => {
setTimeout(() => {
set({ counter: get().counter + 1 });
}, 1000);
});
const { result } = setUp({ counter: 0 });
const [get, set] = result.current;
// simulate 3 clicks
onClick();
onClick();
onClick();
// fast-forward until all timers have been executed
act(() => {
jest.runAllTimers();
});
const currentState = get();
expect(currentState).toEqual({ counter: 3 });
expect(onClick).toHaveBeenCalledTimes(3);
});

View File

@ -0,0 +1,152 @@
import { act, renderHook } from '@testing-library/react-hooks';
import useList from '../useList';
const setUp = (initialList?: any[]) => renderHook(() => useList(initialList));
it('should init list and utils', () => {
const { result } = setUp([1, 2, 3]);
const [list, utils] = result.current;
expect(list).toEqual([1, 2, 3]);
expect(utils).toStrictEqual({
set: expect.any(Function),
clear: expect.any(Function),
updateAt: expect.any(Function),
remove: expect.any(Function),
push: expect.any(Function),
filter: expect.any(Function),
sort: expect.any(Function),
});
});
it('should init empty list if not initial list provided', () => {
const { result } = setUp();
expect(result.current[0]).toEqual([]);
});
it('should set new list', () => {
const initList = [1, 2, 3];
const { result } = setUp(initList);
const [, utils] = result.current;
act(() => {
utils.set([4, 5, 6]);
});
expect(result.current[0]).toEqual([4, 5, 6]);
expect(result.current[0]).not.toBe(initList); // checking immutability
});
it('should clear current list', () => {
const initList = [1, 2, 3];
const { result } = setUp(initList);
const [, utils] = result.current;
act(() => {
utils.clear();
});
expect(result.current[0]).toEqual([]);
expect(result.current[0]).not.toBe(initList); // checking immutability
});
it('should update element at specific position', () => {
const initList = [1, 2, 3];
const { result } = setUp(initList);
const [, utils] = result.current;
act(() => {
utils.updateAt(1, 'foo');
});
expect(result.current[0]).toEqual([1, 'foo', 3]);
expect(result.current[0]).not.toBe(initList); // checking immutability
});
it('should remove element at specific position', () => {
const initList = [1, 2, 3];
const { result } = setUp(initList);
const [, utils] = result.current;
act(() => {
utils.remove(1);
});
expect(result.current[0]).toEqual([1, 3]);
expect(result.current[0]).not.toBe(initList); // checking immutability
});
it('should push new element at the end of the list', () => {
const initList = [1, 2, 3];
const { result } = setUp(initList);
const [, utils] = result.current;
act(() => {
utils.push(0);
});
expect(result.current[0]).toEqual([1, 2, 3, 0]);
expect(result.current[0]).not.toBe(initList); // checking immutability
});
it('should push duplicated element at the end of the list', () => {
const initList = [1, 2, 3];
const { result } = setUp(initList);
const [, utils] = result.current;
act(() => {
utils.push(2);
});
expect(result.current[0]).toEqual([1, 2, 3, 2]);
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);
const [, utils] = result.current;
act(() => {
utils.filter(n => n < 0);
});
expect(result.current[0]).toEqual([-1, -2, -3]);
expect(result.current[0]).not.toBe(initList); // checking immutability
});
it('should sort current list by default order', () => {
const initList = ['March', 'Jan', 'Feb', 'Dec'];
const { result } = setUp(initList);
const [, utils] = result.current;
act(() => {
utils.sort();
});
expect(result.current[0]).toEqual(['Dec', 'Feb', 'Jan', 'March']);
expect(result.current[0]).not.toBe(initList); // checking immutability
});
it('should sort current list by provided function', () => {
const initList = ['March', 'Jan', 'Feb', 'Dec'];
const { result } = setUp(initList);
const [, utils] = result.current;
act(() => {
utils.sort((a, b) => {
if (a < b) {
return 1;
}
if (a > b) {
return -1;
}
return 0;
});
});
expect(result.current[0]).toEqual(['March', 'Jan', 'Feb', 'Dec']);
expect(result.current[0]).not.toBe(initList); // checking immutability
});

View File

@ -0,0 +1,115 @@
import { act, renderHook } from '@testing-library/react-hooks';
import useMap from '../useMap';
const setUp = (initialMap?: object) => renderHook(() => useMap(initialMap));
it('should init map and utils', () => {
const { result } = setUp({ foo: 'bar', a: 1 });
const [map, utils] = result.current;
expect(map).toEqual({ foo: 'bar', a: 1 });
expect(utils).toStrictEqual({
get: expect.any(Function),
set: expect.any(Function),
remove: expect.any(Function),
reset: expect.any(Function),
});
});
it('should init empty map if not initial object provided', () => {
const { result } = setUp();
expect(result.current[0]).toEqual({});
});
it('should get corresponding value for existing provided key', () => {
const { result } = setUp({ foo: 'bar', a: 1 });
const [, utils] = result.current;
let value;
act(() => {
// @ts-ignore
value = utils.get('a');
});
expect(value).toBe(1);
});
it('should get undefined for non-existing provided key', () => {
const { result } = setUp({ foo: 'bar', a: 1 });
const [, utils] = result.current;
let value;
act(() => {
// @ts-ignore
value = utils.get('nonExisting');
});
expect(value).toBeUndefined();
});
it('should set new key-value pair', () => {
const { result } = setUp({ foo: 'bar', a: 1 });
const [, utils] = result.current;
act(() => {
// @ts-ignore
utils.set('newKey', 99);
});
expect(result.current[0]).toEqual({ foo: 'bar', a: 1, newKey: 99 });
});
it('should override current value if setting existing key', () => {
const { result } = setUp({ foo: 'bar', a: 1 });
const [, utils] = result.current;
act(() => {
// @ts-ignore
utils.set('foo', 99);
});
expect(result.current[0]).toEqual({ foo: 99, a: 1 });
});
it('should remove corresponding key-value pair for existing provided key', () => {
const { result } = setUp({ foo: 'bar', a: 1 });
const [, utils] = result.current;
act(() => {
// @ts-ignore
utils.remove('foo');
});
expect(result.current[0]).toEqual({ a: 1 });
});
it('should do nothing if removing non-existing provided key', () => {
const { result } = setUp({ foo: 'bar', a: 1 });
const [, utils] = result.current;
act(() => {
// @ts-ignore
utils.remove('nonExisting');
});
expect(result.current[0]).toEqual({ foo: 'bar', a: 1 });
});
it('should reset map to initial object provided', () => {
const { result } = setUp({ foo: 'bar', a: 1 });
const [, utils] = result.current;
act(() => {
// @ts-ignore
utils.set('z', 99);
});
expect(result.current[0]).toEqual({ foo: 'bar', a: 1, z: 99 });
act(() => {
utils.reset();
});
expect(result.current[0]).toEqual({ foo: 'bar', a: 1 });
});

View File

@ -0,0 +1,28 @@
import { renderHook } from '@testing-library/react-hooks';
import useMountedState from '../useMountedState';
describe('useMountedState', () => {
it('should be defined', () => {
expect(useMountedState).toBeDefined();
});
it('should return a function', () => {
const hook = renderHook(() => useMountedState(), { initialProps: false });
expect(typeof hook.result.current).toEqual('function');
});
it('should return true if component is mounted', () => {
const hook = renderHook(() => useMountedState(), { initialProps: false });
expect(hook.result.current()).toBeTruthy();
});
it('should return false if component is unmounted', () => {
const hook = renderHook(() => useMountedState(), { initialProps: false });
hook.unmount();
expect(hook.result.current()).toBeFalsy();
});
});

View File

@ -0,0 +1,6 @@
import useNumber from '../useNumber';
import useCounter from '../useCounter';
it('should be an alias for useCounter', () => {
expect(useNumber).toBe(useCounter);
});

View File

@ -1,21 +0,0 @@
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { Subject } from 'rxjs';
import { useObservable } from '..';
import useIsomorphicLayoutEffect from '../useIsomorphicLayoutEffect';
jest.mock('../useIsomorphicLayoutEffect');
test('uses layout effect (to subscribe synchronously)', async () => {
const subject = new Subject();
const container = document.createElement('div');
const Demo = ({ obs }) => {
const value = useObservable(obs);
return React.createElement(React.Fragment, {}, value);
};
expect(useIsomorphicLayoutEffect).toHaveBeenCalledTimes(0);
ReactDOM.render(React.createElement(Demo, { obs: subject }), container);
expect(useIsomorphicLayoutEffect).toHaveBeenCalledTimes(1);
});

View File

@ -0,0 +1,108 @@
import { act, renderHook } from '@testing-library/react-hooks';
import { Subject } from 'rxjs';
import useObservable, { Observable } from '../useObservable';
import * as useIsomorphicLayoutEffect from '../useIsomorphicLayoutEffect';
const setUp = (observable: Observable<any>, initialValue?: any) =>
renderHook(() => useObservable(observable, initialValue));
it('should init to initial value provided', () => {
const subject$ = new Subject();
const { result } = setUp(subject$, 123);
expect(result.current).toBe(123);
});
it('should init to undefined if not initial value provided', () => {
const subject$ = new Subject();
const { result } = setUp(subject$);
expect(result.current).toBeUndefined();
});
it('should return latest value of observables', () => {
const subject$ = new Subject();
const { result } = setUp(subject$, 123);
act(() => {
subject$.next(125);
});
expect(result.current).toBe(125);
act(() => {
subject$.next(300);
subject$.next(400);
});
expect(result.current).toBe(400);
});
it('should use layout effect to subscribe synchronously', async () => {
const subject$ = new Subject();
const spy = jest.spyOn(useIsomorphicLayoutEffect, 'default');
expect(spy).toHaveBeenCalledTimes(0);
setUp(subject$, 123);
expect(spy).toHaveBeenCalledTimes(1);
});
it('should subscribe to observable only once', () => {
const subject$ = new Subject();
const spy = jest.spyOn(subject$, 'subscribe');
expect(spy).not.toHaveBeenCalled();
setUp(subject$, 123);
expect(spy).toHaveBeenCalledTimes(1);
act(() => {
subject$.next('a');
});
act(() => {
subject$.next('b');
});
expect(spy).toHaveBeenCalledTimes(1);
});
it('should return updated value when observable changes', () => {
const subject$ = new Subject();
const { result } = setUp(subject$);
expect(result.current).toBeUndefined();
act(() => {
subject$.next('foo');
});
expect(result.current).toBe('foo');
act(() => {
subject$.next('bar');
});
expect(result.current).toBe('bar');
});
it('should unsubscribe from observable', () => {
const subject$ = new Subject();
const unsubscribeMock = jest.fn();
subject$.subscribe = jest.fn().mockReturnValue({
unsubscribe: unsubscribeMock,
});
const { unmount } = setUp(subject$);
expect(unsubscribeMock).not.toHaveBeenCalled();
act(() => {
subject$.next('foo');
});
expect(unsubscribeMock).not.toHaveBeenCalled();
act(() => {
subject$.next('bar');
});
expect(unsubscribeMock).not.toHaveBeenCalled();
unmount();
expect(unsubscribeMock).toHaveBeenCalledTimes(1);
});

View File

@ -1,107 +0,0 @@
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { act, renderHook } from 'react-hooks-testing-library';
import { Subject } from 'rxjs';
import { useObservable } from '..';
let container: HTMLDivElement | null;
beforeEach(() => {
container = document.createElement('div');
document.body.appendChild(container);
});
afterEach(() => {
document.body.removeChild(container!);
container = null;
});
test('default initial value is undefined', () => {
const subject$ = new Subject();
const { result } = renderHook(() => useObservable(subject$));
expect(result.current).toBe(undefined);
});
test('can specify initial value', () => {
const subject$ = new Subject();
const { result } = renderHook(() => useObservable(subject$, 123));
expect(result.current).toBe(123);
});
test('returns the latest value of observables', () => {
const subject$ = new Subject();
const { result } = renderHook(() => useObservable(subject$, 123));
act(() => {
subject$.next(125);
});
expect(result.current).toBe(125);
act(() => {
subject$.next(300);
subject$.next(400);
});
expect(result.current).toBe(400);
});
test('subscribes to observable only once', async () => {
const subject = new Subject();
const spy = jest.spyOn(subject, 'subscribe');
expect(spy).toHaveBeenCalledTimes(0);
const Demo = ({ obs }) => {
const value = useObservable(obs);
return <>{value}</>;
};
ReactDOM.render(<Demo obs={subject} />, container);
expect(spy).toHaveBeenCalledTimes(1);
await new Promise(r => setTimeout(r, 1));
act(() => {
subject.next('a');
});
await new Promise(r => setTimeout(r, 1));
act(() => {
subject.next('b');
});
expect(spy).toHaveBeenCalledTimes(1);
});
test('re-renders component as obsevable changes', async () => {
const subject = new Subject();
let cnt = 0;
const Demo = ({ obs }) => {
cnt++;
const value = useObservable(obs);
return <>{value}</>;
};
ReactDOM.render(<Demo obs={subject} />, container);
await new Promise(r => setTimeout(r, 1));
expect(cnt).toBe(1);
expect(container.innerHTML).toBe('');
act(() => {
subject.next('a');
});
await new Promise(r => setTimeout(r, 1));
expect(cnt).toBe(2);
expect(container.innerHTML).toBe('a');
act(() => {
subject.next('b');
});
await new Promise(r => setTimeout(r, 1));
expect(cnt).toBe(3);
expect(container.innerHTML).toBe('b');
});

View File

@ -0,0 +1,23 @@
import { renderHook } from '@testing-library/react-hooks';
import usePrevious from '../usePrevious';
const setUp = () => renderHook(({ state }) => usePrevious(state), { initialProps: { state: 0 } });
it('should return undefined on initial render', () => {
const { result } = setUp();
expect(result.current).toBeUndefined();
});
it('should always return previous state after each update', () => {
const { result, rerender } = setUp();
rerender({ state: 2 });
expect(result.current).toBe(0);
rerender({ state: 4 });
expect(result.current).toBe(2);
rerender({ state: 6 });
expect(result.current).toBe(4);
});

View File

@ -1,22 +0,0 @@
import { cleanup, renderHook } from 'react-hooks-testing-library';
import usePrevious from '../usePrevious';
afterEach(cleanup);
describe('usePrevious', () => {
it('should be defined', () => {
expect(usePrevious).toBeDefined();
});
const hook = renderHook(props => usePrevious(props), { initialProps: 0 });
it('should return undefined on initial render', () => {
expect(hook.result.current).toBe(undefined);
});
it('should return previous state after update', () => {
hook.rerender(1);
hook.rerender(2);
expect(hook.result.current).toBe(1);
});
});

View File

@ -0,0 +1,42 @@
import { act, renderHook } from '@testing-library/react-hooks';
import useSetState from '../useSetState';
const setUp = (initialState?: object) => renderHook(() => useSetState(initialState));
it('should init state and setter', () => {
const { result } = setUp({ foo: 'bar' });
const [state, setState] = result.current;
expect(state).toEqual({ foo: 'bar' });
expect(setState).toBeInstanceOf(Function);
});
it('should init empty state if not initial state provided', () => {
const { result } = setUp();
expect(result.current[0]).toEqual({});
});
it('should merge changes into current state when providing object', () => {
const { result } = setUp({ foo: 'bar', count: 1 });
const [state, setState] = result.current;
act(() => {
// @ts-ignore
setState({ count: state.count + 1, someBool: true });
});
expect(result.current[0]).toEqual({ foo: 'bar', count: 2, someBool: true });
});
it('should merge changes into current state when providing function', () => {
const { result } = setUp({ foo: 'bar', count: 1 });
const [, setState] = result.current;
act(() => {
// @ts-ignore
setState(prevState => ({ count: prevState.count + 1, someBool: true }));
});
expect(result.current[0]).toEqual({ foo: 'bar', count: 2, someBool: true });
});

View File

@ -1,8 +1,6 @@
import { cleanup, renderHook } from 'react-hooks-testing-library';
import { renderHook } from '@testing-library/react-hooks';
import useTitle from '../useTitle';
afterEach(cleanup);
describe('useTitle', () => {
it('should be defined', () => {
expect(useTitle).toBeDefined();

View File

@ -0,0 +1,83 @@
import { act, renderHook } from '@testing-library/react-hooks';
import useToggle from '../useToggle';
const setUp = (initialValue: boolean) => renderHook(() => useToggle(initialValue));
it('should init state to true', () => {
const { result } = setUp(true);
expect(result.current[0]).toBe(true);
expect(typeof result.current[1]).toBe('function');
});
it('should init state to false', () => {
const { result } = setUp(false);
expect(result.current[0]).toBe(false);
expect(result.current[1]).toBeInstanceOf(Function);
});
it('should set state to true', () => {
const { result } = setUp(false);
const [, toggle] = result.current;
expect(result.current[0]).toBe(false);
act(() => {
toggle(true);
});
expect(result.current[0]).toBe(true);
});
it('should set state to false', () => {
const { result } = setUp(true);
const [, toggle] = result.current;
expect(result.current[0]).toBe(true);
act(() => {
toggle(false);
});
expect(result.current[0]).toBe(false);
});
it('should toggle state from true', () => {
const { result } = setUp(true);
const [, toggle] = result.current;
act(() => {
toggle();
});
expect(result.current[0]).toBe(false);
});
it('should toggle state from false', () => {
const { result } = setUp(false);
const [, toggle] = result.current;
act(() => {
toggle();
});
expect(result.current[0]).toBe(true);
});
it('should ignore non-boolean parameters and toggle state', () => {
const { result } = setUp(true);
const [, toggle] = result.current;
act(() => {
toggle('string');
});
expect(result.current[0]).toBe(false);
act(() => {
toggle({});
});
expect(result.current[0]).toBe(true);
});

View File

@ -1,49 +0,0 @@
import { act, cleanup, renderHook } from 'react-hooks-testing-library';
import useToggle from '../useToggle';
afterEach(cleanup);
describe('useToggle', () => {
it('should be defined', () => {
expect(useToggle).toBeDefined();
});
const hook = renderHook(props => useToggle(props), { initialProps: false });
it('should return initial state on initial render', () => {
expect(hook.result.current[0]).toBe(false);
});
it('should update state with correct value', () => {
hook.rerender(true);
expect(hook.result.current[0]).toBe(true);
act(() => {
hook.result.current[1](false);
});
expect(hook.result.current[0]).toBe(false);
});
// it('should toggle state without a value parameter', () => {
// act(() => {
// hook.result.current[1]();
// });
// expect(hook.result.current[0]).toBe(true);
// });
// it('should ignore non-boolean parameters', () => {
// act(() => {
// hook.result.current[1]('string');
// });
// expect(hook.result.current[0]).toBe(true);
// act(() => {
// hook.result.current[1]({});
// });
// expect(hook.result.current[0]).toBe(false);
// });
});

View File

@ -1,4 +1,4 @@
import { act, cleanup, renderHook } from 'react-hooks-testing-library';
import { act, renderHook } from '@testing-library/react-hooks';
import useWindowSize from '../useWindowSize';
// simulate window resize
@ -17,8 +17,6 @@ function fireResize(type, value) {
window.dispatchEvent(new Event('resize'));
}
afterEach(cleanup);
describe('useWindowSize', () => {
it('should be defined', () => {
expect(useWindowSize).toBeDefined();

View File

@ -44,6 +44,7 @@ export { default as useMedia } from './useMedia';
export { default as useMediaDevices } from './useMediaDevices';
export { default as useMotion } from './useMotion';
export { default as useMount } from './useMount';
export { default as useMountedState } from './useMountedState';
export { default as useMouse } from './useMouse';
export { default as useMouseHovered } from './useMouseHovered';
export { default as useNetwork } from './useNetwork';

View File

@ -1,7 +1,7 @@
import { useEffect, useState } from 'react';
import useMount from './useMount';
const useKeyboardJs = (combination: string) => {
const useKeyboardJs = (combination: string | string[]) => {
const [state, set] = useState<[boolean, null | KeyboardEvent]>([false, null]);
const [keyboardJs, setKeyboardJs] = useState<any>(null);

15
src/useMountedState.ts Normal file
View File

@ -0,0 +1,15 @@
import { useEffect, useRef } from 'react';
export default function useMountedState(): () => boolean {
const mountedRef = useRef<boolean>(false);
useEffect(() => {
mountedRef.current = true;
return () => {
mountedRef.current = false;
};
});
return () => mountedRef.current;
}

392
yarn.lock
View File

@ -1528,7 +1528,7 @@
dependencies:
regenerator-runtime "^0.13.2"
"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.2", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5":
"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.2", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5":
version "7.4.5"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.4.5.tgz#582bb531f5f9dc67d2fcb682979894f75e253f12"
integrity sha512-TuI4qpWZP6lGOGIuGWtp9sPluqYICmbk8T/1vpSysqJxRPkudh/ofFWyqdcMsDf2s7KvDL4/YHgKyvcS3g9CJQ==
@ -1986,14 +1986,6 @@
source-map "^0.6.1"
write-file-atomic "2.4.1"
"@jest/types@^24.7.0":
version "24.7.0"
resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.7.0.tgz#c4ec8d1828cdf23234d9b4ee31f5482a3f04f48b"
integrity sha512-ipJUa2rFWiKoBqMKP63Myb6h9+iT3FHRTF2M8OR6irxWzItisa8i4dcSg14IbvmXUnBlHBlUQPYUHWyX3UPpYA==
dependencies:
"@types/istanbul-lib-coverage" "^2.0.0"
"@types/yargs" "^12.0.9"
"@jest/types@^24.8.0":
version "24.8.0"
resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.8.0.tgz#f31e25948c58f0abd8c845ae26fcea1491dea7ad"
@ -2188,21 +2180,16 @@
into-stream "^4.0.0"
lodash "^4.17.4"
"@sheerun/mutationobserver-shim@^0.3.2":
version "0.3.2"
resolved "https://registry.yarnpkg.com/@sheerun/mutationobserver-shim/-/mutationobserver-shim-0.3.2.tgz#8013f2af54a2b7d735f71560ff360d3a8176a87b"
integrity sha512-vTCdPp/T/Q3oSqwHmZ5Kpa9oI7iLtGl3RQaA/NyLHikvcrPxACkkKVr/XzkSPJWXHRhKGzVvb0urJsbMlRxi1Q==
"@storybook/addon-actions@5.1.9":
version "5.1.9"
resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-5.1.9.tgz#a515b62b109cb886ccd75ef2f5b12f8c27b43dd3"
integrity sha512-h/csHPotBESyEUYlML3yyF2jUlDChB+u3TUNC3Ztzh/x7HzLqy88SL0INSIdY0dCBGx4TK5Gh+rMI7z28Hfdyw==
"@storybook/addon-actions@5.1.10":
version "5.1.10"
resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-5.1.10.tgz#8ed4272a6afc68f4a30372da2eeff414f0fe6ecd"
integrity sha512-njl2AHBGi27NvisOB8LFnWH/3RcyJT/CW7tl1cvV2j5FH2oBjq5MsjxKyJIcKwC677k1Wr8G8fw/zSEHrPpmgA==
dependencies:
"@storybook/addons" "5.1.9"
"@storybook/api" "5.1.9"
"@storybook/components" "5.1.9"
"@storybook/core-events" "5.1.9"
"@storybook/theming" "5.1.9"
"@storybook/addons" "5.1.10"
"@storybook/api" "5.1.10"
"@storybook/components" "5.1.10"
"@storybook/core-events" "5.1.10"
"@storybook/theming" "5.1.10"
core-js "^3.0.1"
fast-deep-equal "^2.0.1"
global "^4.3.2"
@ -2213,16 +2200,16 @@
react-inspector "^3.0.2"
uuid "^3.3.2"
"@storybook/addon-knobs@5.1.9":
version "5.1.9"
resolved "https://registry.yarnpkg.com/@storybook/addon-knobs/-/addon-knobs-5.1.9.tgz#74db07fd644b41e63274f8754fbfb18f43d4cf01"
integrity sha512-7/bICMYtR9CaTqfZX1kT2pBOTLZo3HxeslyQKWWsWlNElV33Ym2d0PPL5eS36eFxG/ZOp6lQWIFhunNnlmP5xg==
"@storybook/addon-knobs@5.1.10":
version "5.1.10"
resolved "https://registry.yarnpkg.com/@storybook/addon-knobs/-/addon-knobs-5.1.10.tgz#f5d9f21090e28046169a0aa0418de59bd92c21fd"
integrity sha512-j5wXBIPGQxK+guFDAi8xNBdUnyQglhDplVoC9SswkSMarqtWq02TT+OLN2VSBgpvzHmhLUW3autjJGfmwP4ltQ==
dependencies:
"@storybook/addons" "5.1.9"
"@storybook/client-api" "5.1.9"
"@storybook/components" "5.1.9"
"@storybook/core-events" "5.1.9"
"@storybook/theming" "5.1.9"
"@storybook/addons" "5.1.10"
"@storybook/client-api" "5.1.10"
"@storybook/components" "5.1.10"
"@storybook/core-events" "5.1.10"
"@storybook/theming" "5.1.10"
copy-to-clipboard "^3.0.8"
core-js "^3.0.1"
escape-html "^1.0.3"
@ -2235,18 +2222,18 @@
react-lifecycles-compat "^3.0.4"
react-select "^2.2.0"
"@storybook/addon-notes@5.1.9":
version "5.1.9"
resolved "https://registry.yarnpkg.com/@storybook/addon-notes/-/addon-notes-5.1.9.tgz#7a19373589b4280b9a10a107a0357e63d2d56f5c"
integrity sha512-UE+/RNysKRo2ZqCaqllwwV59x2S1laZjF4Netcm0nf9dKNcnqOoSHlTs0t4m8WpmfBQKAde4p+8fJGP2bCM+8A==
"@storybook/addon-notes@5.1.10":
version "5.1.10"
resolved "https://registry.yarnpkg.com/@storybook/addon-notes/-/addon-notes-5.1.10.tgz#92609d64401b962c5eaea0b5235474daa59a0d3f"
integrity sha512-S2I9W7n8xQKuJFxk3dF1RO1o648L+yX/JHR9j9rMHbre+5LuZ/Bev5WOIhHHthKllPqy1/Wxe9ECsGR7L4W2CQ==
dependencies:
"@storybook/addons" "5.1.9"
"@storybook/api" "5.1.9"
"@storybook/client-logger" "5.1.9"
"@storybook/components" "5.1.9"
"@storybook/core-events" "5.1.9"
"@storybook/router" "5.1.9"
"@storybook/theming" "5.1.9"
"@storybook/addons" "5.1.10"
"@storybook/api" "5.1.10"
"@storybook/client-logger" "5.1.10"
"@storybook/components" "5.1.10"
"@storybook/core-events" "5.1.10"
"@storybook/router" "5.1.10"
"@storybook/theming" "5.1.10"
core-js "^3.0.1"
global "^4.3.2"
markdown-to-jsx "^6.9.3"
@ -2254,37 +2241,37 @@
prop-types "^15.7.2"
util-deprecate "^1.0.2"
"@storybook/addon-options@5.1.9":
version "5.1.9"
resolved "https://registry.yarnpkg.com/@storybook/addon-options/-/addon-options-5.1.9.tgz#dc326b94c52a7ee27bf948fb7ca63a6ea3c9736d"
integrity sha512-wQIUw5Uc/5iREtI9eh2wPMlNG0O7jxaTaxGS8Bs6zDzkwiLHcLJCrfk1lPXU6O8ExEzWHpaCmxth8GyfKj8Qtw==
"@storybook/addon-options@5.1.10":
version "5.1.10"
resolved "https://registry.yarnpkg.com/@storybook/addon-options/-/addon-options-5.1.10.tgz#ae6cf58744cee4ed161ffc537bc7e29a7c7337d0"
integrity sha512-DA6r84JYMJ5zACGdPQ7utpig8pUU1wywMMZt43k2IhxKBFcamw0Nmc80vvlTMM4mUu+mevH1ZiuzWxTZU7IcxA==
dependencies:
"@storybook/addons" "5.1.9"
"@storybook/addons" "5.1.10"
core-js "^3.0.1"
util-deprecate "^1.0.2"
"@storybook/addons@5.1.9":
version "5.1.9"
resolved "https://registry.yarnpkg.com/@storybook/addons/-/addons-5.1.9.tgz#ecf218d08508b97ca5e6e0f1ed361081385bd3ff"
integrity sha512-1bavbcS/NiE65DwyKj8c0DmWmz9VekOinB+has2Pqt2bOffZoZwVnbmepcz9hH3GUyvp5fQBYbxTEmTDvF2lLA==
"@storybook/addons@5.1.10":
version "5.1.10"
resolved "https://registry.yarnpkg.com/@storybook/addons/-/addons-5.1.10.tgz#2d8d8ca20b6d9b4652744f5fc00ead483f705435"
integrity sha512-M9b2PCp9RZxDC6wL7vVt2SCKCGXrrEAOsdpMvU569yB1zoUPEiiqElVDwb91O2eAGPnmd2yjImp90kOpKUW0EA==
dependencies:
"@storybook/api" "5.1.9"
"@storybook/channels" "5.1.9"
"@storybook/client-logger" "5.1.9"
"@storybook/api" "5.1.10"
"@storybook/channels" "5.1.10"
"@storybook/client-logger" "5.1.10"
core-js "^3.0.1"
global "^4.3.2"
util-deprecate "^1.0.2"
"@storybook/api@5.1.9":
version "5.1.9"
resolved "https://registry.yarnpkg.com/@storybook/api/-/api-5.1.9.tgz#eec5b2f775392ce0803930104c6ce14fa4931e8b"
integrity sha512-d1HhpOkW+706/WJ9lP5nCqOrp/icvbm0o+6jFFOGJ35AW5O9D8vDBxzvgMEO45jjN4I+rtbcNHQCxshSbPvP9w==
"@storybook/api@5.1.10":
version "5.1.10"
resolved "https://registry.yarnpkg.com/@storybook/api/-/api-5.1.10.tgz#5eeb5d9a7c268e5c89bd40c9a80293a7c72343b8"
integrity sha512-YeZe/71zLMmgT95IMAEZOc9AwL6Y23mWvkZMwFbkokxS9+bU/qmVlQ0B9c3JBzO3OSs7sXaRqyP1o3QkQgVsiw==
dependencies:
"@storybook/channels" "5.1.9"
"@storybook/client-logger" "5.1.9"
"@storybook/core-events" "5.1.9"
"@storybook/router" "5.1.9"
"@storybook/theming" "5.1.9"
"@storybook/channels" "5.1.10"
"@storybook/client-logger" "5.1.10"
"@storybook/core-events" "5.1.10"
"@storybook/router" "5.1.10"
"@storybook/theming" "5.1.10"
core-js "^3.0.1"
fast-deep-equal "^2.0.1"
global "^4.3.2"
@ -2298,33 +2285,33 @@
telejson "^2.2.1"
util-deprecate "^1.0.2"
"@storybook/channel-postmessage@5.1.9":
version "5.1.9"
resolved "https://registry.yarnpkg.com/@storybook/channel-postmessage/-/channel-postmessage-5.1.9.tgz#bd710ca74d7998a234c6b1f38009020d7c34bbc0"
integrity sha512-H71PsnDKW81eflOS48Lv9yK4O8AcoqXL6ohsWvLdrHWIBsH4zpjOIhdWHtmAaT3hyfMy+l49DQ+uCHLECEt55g==
"@storybook/channel-postmessage@5.1.10":
version "5.1.10"
resolved "https://registry.yarnpkg.com/@storybook/channel-postmessage/-/channel-postmessage-5.1.10.tgz#e0a58461d56ef20a87d8bc4df1067e7afc76950e"
integrity sha512-kQZIwltN2cWDXluhCfdModFDK1LHV9ZhNQ1b/uD9vn1c65rQ9u7r4lRajCfS0X1dmAWqz48cBcEurAubNgmswg==
dependencies:
"@storybook/channels" "5.1.9"
"@storybook/client-logger" "5.1.9"
"@storybook/channels" "5.1.10"
"@storybook/client-logger" "5.1.10"
core-js "^3.0.1"
global "^4.3.2"
telejson "^2.2.1"
"@storybook/channels@5.1.9":
version "5.1.9"
resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-5.1.9.tgz#003cfca0b9f1ba6cf47ce68304aedd71bdb55e74"
integrity sha512-R6i7859FsXgY9XFFErVe7gS37wGYpQEEWsO1LzUW7YptGuFTUa8yLgKkNkgfy7Zs61Xm+GiBq8PvS/CWxjotPw==
"@storybook/channels@5.1.10":
version "5.1.10"
resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-5.1.10.tgz#04fd35c05032c675f7816ea1ca873c1a0415c6d9"
integrity sha512-w7n/bV1BLu51KI1eLc75lN9H1ssBc3PZMXk88GkMiKyBVRzPlJA5ixnzH86qwYGReE0dhRpsgHXZ5XmoKaVmPA==
dependencies:
core-js "^3.0.1"
"@storybook/client-api@5.1.9":
version "5.1.9"
resolved "https://registry.yarnpkg.com/@storybook/client-api/-/client-api-5.1.9.tgz#b598efe4ab07bffaeb4cb9e30ed9c21add739df1"
integrity sha512-J5HDtOS7x5YRpF/CMiHdxywV5NIh1i/03Xh2RhG15lmPy87VStIGpLzhF71uCRPLEJinYelcjuXRNAJgRzUOlg==
"@storybook/client-api@5.1.10":
version "5.1.10"
resolved "https://registry.yarnpkg.com/@storybook/client-api/-/client-api-5.1.10.tgz#a10f028f2d33d044e5c3b3daea5d8375323e6a66"
integrity sha512-v2PqiNUhwDlVDLYL94f6LFjdYMToTpuwWh9aeqzt/4PAJUnIcA+2P8+qXiYdJTqQy/u7P72HFMlc9Ru4tl3QFg==
dependencies:
"@storybook/addons" "5.1.9"
"@storybook/client-logger" "5.1.9"
"@storybook/core-events" "5.1.9"
"@storybook/router" "5.1.9"
"@storybook/addons" "5.1.10"
"@storybook/client-logger" "5.1.10"
"@storybook/core-events" "5.1.10"
"@storybook/router" "5.1.10"
common-tags "^1.8.0"
core-js "^3.0.1"
eventemitter3 "^3.1.0"
@ -2334,20 +2321,20 @@
memoizerific "^1.11.3"
qs "^6.6.0"
"@storybook/client-logger@5.1.9":
version "5.1.9"
resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-5.1.9.tgz#87e2f7578416269adeccd407584010bc353f14d3"
integrity sha512-1+Otcn0EFgWNviDPNCR5LtUViADlboz9fmpZc7UY7bgaY5FVNIUO01E4T43tO7fduiRZoEvdltwTuQRm260Vjw==
"@storybook/client-logger@5.1.10":
version "5.1.10"
resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-5.1.10.tgz#f83a8717924dd222e0a6df82ae74701f27e0bb35"
integrity sha512-vB1NoFWRTgcERwodhbgoDwI00eqU8++nXI7GhMS1CY8haZaSp3gyKfHRWyfH+M+YjQuGBRUcvIk4gK6OtSrDOw==
dependencies:
core-js "^3.0.1"
"@storybook/components@5.1.9":
version "5.1.9"
resolved "https://registry.yarnpkg.com/@storybook/components/-/components-5.1.9.tgz#2a5258780fff07172d103287759946dbb4b13e2d"
integrity sha512-F4xcRlifSAfqkuFWtCKRvQDahXyfWBWV2Wa+kYy4YGwEfm3kKtIHVlgdgARL22g9BdYpRFEOJ+42juOu5YvIeQ==
"@storybook/components@5.1.10":
version "5.1.10"
resolved "https://registry.yarnpkg.com/@storybook/components/-/components-5.1.10.tgz#4b6436f0b5bb2483fb231bee263d173a9ed7d241"
integrity sha512-QUQeeQp1xNWiL4VlxFAea0kqn2zvBfmfPlUddOFO9lBhT6pVy0xYPjXjbTVWjVcYzZpyUNWw5GplqrR5jhlaCA==
dependencies:
"@storybook/client-logger" "5.1.9"
"@storybook/theming" "5.1.9"
"@storybook/client-logger" "5.1.10"
"@storybook/theming" "5.1.10"
core-js "^3.0.1"
global "^4.3.2"
markdown-to-jsx "^6.9.1"
@ -2365,32 +2352,32 @@
recompose "^0.30.0"
simplebar-react "^1.0.0-alpha.6"
"@storybook/core-events@5.1.9":
version "5.1.9"
resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-5.1.9.tgz#441a6297e2ccfa743e15d1db1f4ac445b91f40d8"
integrity sha512-jHe2uyoLj9i6fntHtOj5azfGdLOb75LF0e1xXE8U2SX7Zp3uwbLAcfJ+dPStdc/q+f/wBiip3tH1dIjaNuUiMw==
"@storybook/core-events@5.1.10":
version "5.1.10"
resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-5.1.10.tgz#5aed88c572036b6bd6dfff28976ee96e6e175d7a"
integrity sha512-Lvu/rNcgS+XCkQKSGdNpUSWjpFF9AOSHPXsvkwHbRwJYdMDn3FznlXfDUiubOWtsziXHB6vl3wkKDlH+ckb32Q==
dependencies:
core-js "^3.0.1"
"@storybook/core@5.1.9":
version "5.1.9"
resolved "https://registry.yarnpkg.com/@storybook/core/-/core-5.1.9.tgz#8b30507676531fd41ac333b7c71b1c0db6b8da35"
integrity sha512-P3aavCnl3Cl3WMXVERjQqnqV1Z8tN0tyOTqqiGb1fMxITSE8uZNvp33Dl0K3jr1PBl9trW+2t7eHH4h0sguLlQ==
"@storybook/core@5.1.10":
version "5.1.10"
resolved "https://registry.yarnpkg.com/@storybook/core/-/core-5.1.10.tgz#53d23d07716aa2721e1572d44a7f05967d7da39e"
integrity sha512-zkNjufOFrLpFpmr73F/gaJh0W0vWqXIo5zrKvQt1LqmMeCU/v8MstHi4XidlK43UpeogfaXl5tjNCQDO/bd0Dw==
dependencies:
"@babel/plugin-proposal-class-properties" "^7.3.3"
"@babel/plugin-proposal-object-rest-spread" "^7.3.2"
"@babel/plugin-syntax-dynamic-import" "^7.2.0"
"@babel/plugin-transform-react-constant-elements" "^7.2.0"
"@babel/preset-env" "^7.4.5"
"@storybook/addons" "5.1.9"
"@storybook/channel-postmessage" "5.1.9"
"@storybook/client-api" "5.1.9"
"@storybook/client-logger" "5.1.9"
"@storybook/core-events" "5.1.9"
"@storybook/node-logger" "5.1.9"
"@storybook/router" "5.1.9"
"@storybook/theming" "5.1.9"
"@storybook/ui" "5.1.9"
"@storybook/addons" "5.1.10"
"@storybook/channel-postmessage" "5.1.10"
"@storybook/client-api" "5.1.10"
"@storybook/client-logger" "5.1.10"
"@storybook/core-events" "5.1.10"
"@storybook/node-logger" "5.1.10"
"@storybook/router" "5.1.10"
"@storybook/theming" "5.1.10"
"@storybook/ui" "5.1.10"
airbnb-js-shims "^1 || ^2"
autoprefixer "^9.4.9"
babel-plugin-add-react-displayname "^0.0.5"
@ -2444,10 +2431,10 @@
webpack-dev-middleware "^3.7.0"
webpack-hot-middleware "^2.25.0"
"@storybook/node-logger@5.1.9":
version "5.1.9"
resolved "https://registry.yarnpkg.com/@storybook/node-logger/-/node-logger-5.1.9.tgz#4aacf0096811fde1639fc9d1d2d521f7220dd4be"
integrity sha512-rcSuI5n53hDMHW83gl5TR0Yn885/i2XY0AzX1DsbTeGOl3x5LhrCSZsZWetKGcx7zsO4n7o5mQszLuN1JlyE8A==
"@storybook/node-logger@5.1.10":
version "5.1.10"
resolved "https://registry.yarnpkg.com/@storybook/node-logger/-/node-logger-5.1.10.tgz#92c80b46177687cd8fda1f93a055c22711984154"
integrity sha512-Z4UKh7QBOboQhUF5S/dKOx3OWWCNZGwYu8HZa/O+P68+XnQDhuZCYwqWG49xFhZd0Jb0W9gdUL2mWJw5POG9PA==
dependencies:
chalk "^2.4.2"
core-js "^3.0.1"
@ -2455,16 +2442,16 @@
pretty-hrtime "^1.0.3"
regenerator-runtime "^0.12.1"
"@storybook/react@5.1.9":
version "5.1.9"
resolved "https://registry.yarnpkg.com/@storybook/react/-/react-5.1.9.tgz#4052f4b88e91d5a823bb9cbb61104c530fcfb1a1"
integrity sha512-Byykpsttf6p2jv3LvqFtntEYfbUZSNTts0TjcZHNsHoUGmT7/M1PyqTeB7JUcYUNwSgdACY8FbowCrwZwDJDWQ==
"@storybook/react@5.1.10":
version "5.1.10"
resolved "https://registry.yarnpkg.com/@storybook/react/-/react-5.1.10.tgz#a5cf2b7d086e121c969d34100fb03fcfdc74cbed"
integrity sha512-wWy9l83KgbP8P2A8AbkwExEAdA0iznb4jEnCGzP1hAv8Q5LmL3MLPb1dIZqhWrg+E2m3tZei+7A7qu2Q8/cLLw==
dependencies:
"@babel/plugin-transform-react-constant-elements" "^7.2.0"
"@babel/preset-flow" "^7.0.0"
"@babel/preset-react" "^7.0.0"
"@storybook/core" "5.1.9"
"@storybook/node-logger" "5.1.9"
"@storybook/core" "5.1.10"
"@storybook/node-logger" "5.1.10"
"@svgr/webpack" "^4.0.3"
babel-plugin-add-react-displayname "^0.0.5"
babel-plugin-named-asset-import "^0.3.1"
@ -2481,10 +2468,10 @@
semver "^6.0.0"
webpack "^4.33.0"
"@storybook/router@5.1.9":
version "5.1.9"
resolved "https://registry.yarnpkg.com/@storybook/router/-/router-5.1.9.tgz#8cd97bea4f2acf8ec5f6694d06fb0633dde33417"
integrity sha512-eAmeerE/OTIwCV7WBnb1BPINVN1GTSMsUXLNWpqSISuyWJ+NZAJlObFkvXoc57QSQlv0cvXlm1FMkmRt8ku1Hw==
"@storybook/router@5.1.10":
version "5.1.10"
resolved "https://registry.yarnpkg.com/@storybook/router/-/router-5.1.10.tgz#d3cffd3f1105eb665882f389746ccabbb98c3c16"
integrity sha512-BdG6/essPZFHCP2ewCG0gYFQfmuuTSHXAB5fd/rwxLSYj1IzNznC5OxkvnSaTr4rgoxxaW/z1hbN1NuA0ivlFA==
dependencies:
"@reach/router" "^1.2.1"
core-js "^3.0.1"
@ -2492,14 +2479,14 @@
memoizerific "^1.11.3"
qs "^6.6.0"
"@storybook/theming@5.1.9":
version "5.1.9"
resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-5.1.9.tgz#c425f5867fae0db79e01112853b1808332a5f1a2"
integrity sha512-4jIFJwTWVf9tsv27noLoFHlKC2Jl9DHV3q+rxGPU8bTNbufCu4oby82SboO5GAKuS3eu1cxL1YY9pYad9WxfHg==
"@storybook/theming@5.1.10":
version "5.1.10"
resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-5.1.10.tgz#f9bd519cdf9cccf730656e3f5fd56a339dd07c9f"
integrity sha512-5cN1lmdVUwAR8U3T49Lfb8JW5RBvxBSPGZpUmbLGz1zi0tWBJgYXoGtw4RbTBjV9kCQOXkHGH12AsdDxHh931w==
dependencies:
"@emotion/core" "^10.0.9"
"@emotion/styled" "^10.0.7"
"@storybook/client-logger" "5.1.9"
"@storybook/client-logger" "5.1.10"
common-tags "^1.8.0"
core-js "^3.0.1"
deep-object-diff "^1.1.0"
@ -2510,19 +2497,19 @@
prop-types "^15.7.2"
resolve-from "^5.0.0"
"@storybook/ui@5.1.9":
version "5.1.9"
resolved "https://registry.yarnpkg.com/@storybook/ui/-/ui-5.1.9.tgz#406667469e6dbdf320086647d8d80776bb051a51"
integrity sha512-guzKv4VYM+06BzMXeO3QqlX0IwUHyeS6lwdPCL8Oy2V4Gi2IYHHiD6Hr1NgnBO18j9luxE38f4Ii7gEIzXMFbQ==
"@storybook/ui@5.1.10":
version "5.1.10"
resolved "https://registry.yarnpkg.com/@storybook/ui/-/ui-5.1.10.tgz#4262b1b09efa43d125d694452ae879b89071edd1"
integrity sha512-ezkoVtzoKh93z2wzkqVIqyrIzTkj8tizgAkoPa7mUAbLCxu6LErHITODQoyEiJWI4Epy3yU9GYXFWwT71hdwsA==
dependencies:
"@storybook/addons" "5.1.9"
"@storybook/api" "5.1.9"
"@storybook/channels" "5.1.9"
"@storybook/client-logger" "5.1.9"
"@storybook/components" "5.1.9"
"@storybook/core-events" "5.1.9"
"@storybook/router" "5.1.9"
"@storybook/theming" "5.1.9"
"@storybook/addons" "5.1.10"
"@storybook/api" "5.1.10"
"@storybook/channels" "5.1.10"
"@storybook/client-logger" "5.1.10"
"@storybook/components" "5.1.10"
"@storybook/core-events" "5.1.10"
"@storybook/router" "5.1.10"
"@storybook/theming" "5.1.10"
copy-to-clipboard "^3.0.8"
core-js "^3.0.1"
core-js-pure "^3.0.1"
@ -2655,6 +2642,15 @@
"@svgr/plugin-svgo" "^4.0.3"
loader-utils "^1.1.0"
"@testing-library/react-hooks@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@testing-library/react-hooks/-/react-hooks-1.1.0.tgz#14b6b5c7c3d0e2cb3e55e9cbb248b44321641c64"
integrity sha512-piE/ceQoNf134FFVXBABDbttBJ8eLPD4eg7zIciVJv92RyvoIsBHCvvG8Vd4IG5pyuWYrkLsZTO8ucZBwa4twA==
dependencies:
"@babel/runtime" "^7.4.2"
"@types/react" "^16.8.22"
"@types/react-test-renderer" "^16.8.2"
"@types/babel__core@^7.1.0":
version "7.1.0"
resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.0.tgz#710f2487dda4dcfd010ca6abb2b4dc7394365c51"
@ -2732,10 +2728,10 @@
resolved "https://registry.yarnpkg.com/@types/jest-diff/-/jest-diff-20.0.1.tgz#35cc15b9c4f30a18ef21852e255fdb02f6d59b89"
integrity sha512-yALhelO3i0hqZwhjtcr6dYyaLoCHbAMshwtj6cGxTvHZAKXHsYGdff6E8EPw3xLKY0ELUTQ69Q1rQiJENnccMA==
"@types/jest@24.0.15":
version "24.0.15"
resolved "https://registry.yarnpkg.com/@types/jest/-/jest-24.0.15.tgz#6c42d5af7fe3b44ffff7cc65de7bf741e8fa427f"
integrity sha512-MU1HIvWUme74stAoc3mgAi+aMlgKOudgEvQDIm1v4RkrDudBh1T+NFp5sftpBAdXdx1J0PbdpJ+M2EsSOi1djA==
"@types/jest@24.0.16":
version "24.0.16"
resolved "https://registry.yarnpkg.com/@types/jest/-/jest-24.0.16.tgz#8d3e406ec0f0dc1688d6711af3062ff9bd428066"
integrity sha512-JrAiyV+PPGKZzw6uxbI761cHZ0G7QMOHXPhtSpcl08rZH6CswXaaejckn3goFKmF7M3nzEoJ0lwYCbqLMmjziQ==
dependencies:
"@types/jest-diff" "*"
@ -2764,6 +2760,13 @@
resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8"
integrity sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw==
"@types/react-test-renderer@^16.8.2":
version "16.8.3"
resolved "https://registry.yarnpkg.com/@types/react-test-renderer/-/react-test-renderer-16.8.3.tgz#b6ca14d5fe4c742fd6d68ef42d45e3b5c6dd470a"
integrity sha512-vEEYh6gFk3jkPHqRe7N5CxWA+yb92hCZxNyhq/1Wj3mClqVWLJYakJDMp3iFmntCgEq96m68N9Oad3wOHm+pdQ==
dependencies:
"@types/react" "*"
"@types/react-wait@^0.3.0":
version "0.3.0"
resolved "https://registry.yarnpkg.com/@types/react-wait/-/react-wait-0.3.0.tgz#6f7ef17571a17e72c7864ede8cf7d3aa525a005e"
@ -2779,6 +2782,14 @@
"@types/prop-types" "*"
csstype "^2.2.0"
"@types/react@^16.8.22":
version "16.8.24"
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.8.24.tgz#8d1ea1fcbfa214220da3d3c04e506f1077b0deac"
integrity sha512-VpFHUoD37YNY2+lr/+c7qL/tZsIU/bKuskUF3tmGUArbxIcQdb5j3zvo4cuuzu2A6UaVmVn7sJ4PgWYNFEBGzg==
dependencies:
"@types/prop-types" "*"
csstype "^2.2.0"
"@types/stack-utils@^1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e"
@ -5697,16 +5708,6 @@ dom-serializer@0:
domelementtype "~1.1.1"
entities "~1.1.1"
dom-testing-library@^3.19.0:
version "3.19.0"
resolved "https://registry.yarnpkg.com/dom-testing-library/-/dom-testing-library-3.19.0.tgz#652ade2cd93ae98beb52b2878eeb9420d7599832"
integrity sha512-gkGXP5GevcjC24Tk6Y6RwrZ7Nz0Ul4bchXV4yHLcnMidMp/EdBCvtHEgHTsZ2yZ4DhUpLowGbJv/1u1Z7bPvtw==
dependencies:
"@babel/runtime" "^7.3.4"
"@sheerun/mutationobserver-shim" "^0.3.2"
pretty-format "^24.5.0"
wait-for-expect "^1.1.0"
dom-walk@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018"
@ -6871,10 +6872,10 @@ getpass@^0.1.1:
dependencies:
assert-plus "^1.0.0"
gh-pages@2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/gh-pages/-/gh-pages-2.0.1.tgz#aefe47a43b8d9d2aa3130576b33fe95641e29a2f"
integrity sha512-uFlk3bukljeiWKQ2XvPfjcSi/ou7IfoDf2p+Fj672saLAr8bnOdFVqI/JSgrSgInKpCg5BksxEwGUl++dbg8Dg==
gh-pages@2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/gh-pages/-/gh-pages-2.1.0.tgz#dcf519825d77d3a3ee78763076f4158403fc88c4"
integrity sha512-QmV1fh/2W5GZkfoLsG4g6dRTWiNYuCetMQmm8CL6Us8JVnAufYtS0uJPD8NYogmNB4UZzdRG44uPAL+jcBzEwQ==
dependencies:
async "^2.6.1"
commander "^2.18.0"
@ -7373,10 +7374,10 @@ humanize-url@^1.0.0:
normalize-url "^1.0.0"
strip-url-auth "^1.0.0"
husky@3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/husky/-/husky-3.0.1.tgz#06152c28e129622b05fa09c494209de8cf2dfb59"
integrity sha512-PXBv+iGKw23GHUlgELRlVX9932feFL407/wHFwtsGeArp0dDM4u+/QusSQwPKxmNgjpSL+ustbOdQ2jetgAZbA==
husky@3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/husky/-/husky-3.0.2.tgz#e78fd2ae16edca59fc88e56aeb8d70acdcc1c082"
integrity sha512-WXCtaME2x0o4PJlKY4ap8BzLA+D0zlvefqAvLCPriOOu+x0dpO5uc5tlB7CY6/0SE2EESmoZsj4jW5D09KrJoA==
dependencies:
chalk "^2.4.2"
cosmiconfig "^5.2.1"
@ -9338,13 +9339,13 @@ map-visit@^1.0.0:
dependencies:
object-visit "^1.0.0"
markdown-loader@5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/markdown-loader/-/markdown-loader-5.0.0.tgz#d6af0f2d5fe7713fb692cbd85b547ff0ef26baa8"
integrity sha512-CnRuBrTQNJ2VNlyfPJl+14QU6Sfscse4M6TpwuY0KDuCafMHv6vAcVYInphXFtdvtvjG5kMpF+PwN6CWke0M3A==
markdown-loader@5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/markdown-loader/-/markdown-loader-5.1.0.tgz#4efd5006b1514ca966141c661a47e542a9836e6e"
integrity sha512-xtQNozLEL+55ZSPTNwro8epZqf1h7HjAZd/69zNe8lbckDiGVHeLQm849bXzocln2pwRK2A/GrW/7MAmwjcFog==
dependencies:
loader-utils "^1.2.3"
marked "^0.6.0"
marked "^0.7.0"
markdown-to-jsx@^6.9.1:
version "6.9.2"
@ -9374,10 +9375,10 @@ marked-terminal@^3.2.0:
node-emoji "^1.4.1"
supports-hyperlinks "^1.0.1"
marked@^0.6.0:
version "0.6.1"
resolved "https://registry.yarnpkg.com/marked/-/marked-0.6.1.tgz#a63addde477bca9613028de4b2bc3629e53a0562"
integrity sha512-+H0L3ibcWhAZE02SKMqmvYsErLo4EAVJxu5h3bHBBDvvjeWXtl92rGUSBYHL2++5Y+RSNgl8dYOAXcYe7lp1fA==
marked@^0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/marked/-/marked-0.7.0.tgz#b64201f051d271b1edc10a04d1ae9b74bb8e5c0e"
integrity sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==
material-colors@^1.2.1:
version "1.2.6"
@ -11307,16 +11308,6 @@ pretty-error@^2.1.1:
renderkid "^2.0.1"
utila "~0.4"
pretty-format@^24.5.0:
version "24.7.0"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.7.0.tgz#d23106bc2edcd776079c2daa5da02bcb12ed0c10"
integrity sha512-apen5cjf/U4dj7tHetpC7UEFCvtAgnNZnBDkfPv3fokzIqyOJckAG9OlAPC1BlFALnqT/lGB2tl9EJjlK6eCsA==
dependencies:
"@jest/types" "^24.7.0"
ansi-regex "^4.0.0"
ansi-styles "^3.2.0"
react-is "^16.8.4"
pretty-format@^24.8.0:
version "24.8.0"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.8.0.tgz#8dae7044f58db7cb8be245383b565a963e3c27f2"
@ -11759,14 +11750,6 @@ react-helmet-async@^1.0.2:
react-fast-compare "2.0.4"
shallowequal "1.1.0"
react-hooks-testing-library@0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/react-hooks-testing-library/-/react-hooks-testing-library-0.4.1.tgz#481b960d647d3cc7c8bbaf410014daa8ce0b1360"
integrity sha512-ogmlyW7ycZe3+HIk1Y+FUV5ExpZwLi/RlF1qGLLbTkUdaAsGgp9fSF+wFNWi2KNKBTWG0FkkqOrLkcwq0z3ebQ==
dependencies:
"@babel/runtime" "^7.4.2"
react-testing-library "^6.0.3"
react-hotkeys@2.0.0-pre4:
version "2.0.0-pre4"
resolved "https://registry.yarnpkg.com/react-hotkeys/-/react-hotkeys-2.0.0-pre4.tgz#a1c248a51bdba4282c36bf3204f80d58abc73333"
@ -11795,7 +11778,7 @@ react-is@^16.7.0, react-is@^16.8.1:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.4.tgz#90f336a68c3a29a096a3d648ab80e87ec61482a2"
integrity sha512-PVadd+WaUDOAciICm/J1waJaSvgq+4rHE/K70j0PFqKhkTBsPv/82UGQJNXAngz1fOQLLxI6z1sEDmJDQhCTAA==
react-is@^16.8.4:
react-is@^16.8.4, react-is@^16.8.6:
version "16.8.6"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.6.tgz#5bbc1e2d29141c9fbdfed456343fe2bc430a6a16"
integrity sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==
@ -11868,13 +11851,15 @@ react-syntax-highlighter@^8.0.1:
prismjs "^1.8.4"
refractor "^2.4.1"
react-testing-library@^6.0.3:
version "6.1.2"
resolved "https://registry.yarnpkg.com/react-testing-library/-/react-testing-library-6.1.2.tgz#f6bba6eeecedac736eb00b22b4c70bae04535a4f"
integrity sha512-z69lhRDGe7u/NOjDCeFRoe1cB5ckJ4656n0tj/Fdcr6OoBUu7q9DBw0ftR7v5i3GRpdSWelnvl+feZFOyXyxwg==
react-test-renderer@^16.8.6:
version "16.8.6"
resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.8.6.tgz#188d8029b8c39c786f998aa3efd3ffe7642d5ba1"
integrity sha512-H2srzU5IWYT6cZXof6AhUcx/wEyJddQ8l7cLM/F7gDXYyPr4oq+vCIxJYXVGhId1J706sqziAjuOEjyNkfgoEw==
dependencies:
"@babel/runtime" "^7.4.2"
dom-testing-library "^3.19.0"
object-assign "^4.1.1"
prop-types "^15.6.2"
react-is "^16.8.6"
scheduler "^0.13.6"
react-textarea-autosize@^7.1.0:
version "7.1.0"
@ -12643,10 +12628,10 @@ select@^1.1.2:
resolved "https://registry.yarnpkg.com/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d"
integrity sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=
semantic-release@15.13.18:
version "15.13.18"
resolved "https://registry.yarnpkg.com/semantic-release/-/semantic-release-15.13.18.tgz#72e284c6f7cb7817e1aaaa0a9d73600a9447d146"
integrity sha512-JtfdrhF1zRm91nJH/Rg3taftbWGwktJqqrJJdbmZGKYx63cfC4PoaS0jxRifGJUdmmgW/Kxz8f5bhtB+p1bu8A==
semantic-release@15.13.19:
version "15.13.19"
resolved "https://registry.yarnpkg.com/semantic-release/-/semantic-release-15.13.19.tgz#d1d05b3516fb8701d81f4e6b9be42bafffef13cb"
integrity sha512-6eqqAmzGaJWgP5R5IkWIQK9is+cWUp/A+pwzxf/YaG1hJv1eD25klUP7Y0fedsPOxxI8eLuDUVlEs7U8SOlK0Q==
dependencies:
"@semantic-release/commit-analyzer" "^6.1.0"
"@semantic-release/error" "^2.2.0"
@ -12665,7 +12650,7 @@ semantic-release@15.13.18:
hook-std "^2.0.0"
hosted-git-info "^2.7.1"
lodash "^4.17.4"
marked "^0.6.0"
marked "^0.7.0"
marked-terminal "^3.2.0"
p-locate "^4.0.0"
p-reduce "^2.0.0"
@ -14402,11 +14387,6 @@ w3c-hr-time@^1.0.1:
dependencies:
browser-process-hrtime "^0.1.2"
wait-for-expect@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/wait-for-expect/-/wait-for-expect-1.1.1.tgz#9cd10e07d52810af9e0aaf509872e38f3c3d81ae"
integrity sha512-vd9JOqqEcBbCDhARWhW85ecjaEcfBLuXgVBqatfS3iw6oU4kzAcs+sCNjF+TC9YHPImCW7ypsuQc+htscIAQCw==
walker@^1.0.7, walker@~1.0.5:
version "1.0.7"
resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb"