Add async filtering support to the select-control component (#35839)
* Add async filtering support to the select-control component * Apply comment suggestions * Apply more comment suggestions
This commit is contained in:
parent
0a039a1f13
commit
788b3ef59b
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: patch
|
||||||
|
Type: add
|
||||||
|
|
||||||
|
Add async filtering support to the `__experimentalSelectControl` component
|
|
@ -111,6 +111,7 @@
|
||||||
"@testing-library/dom": "^8.11.3",
|
"@testing-library/dom": "^8.11.3",
|
||||||
"@testing-library/jest-dom": "^5.16.2",
|
"@testing-library/jest-dom": "^5.16.2",
|
||||||
"@testing-library/react": "^12.1.3",
|
"@testing-library/react": "^12.1.3",
|
||||||
|
"@testing-library/react-hooks": "^8.0.1",
|
||||||
"@testing-library/user-event": "^13.5.0",
|
"@testing-library/user-event": "^13.5.0",
|
||||||
"@types/jest": "^27.4.1",
|
"@types/jest": "^27.4.1",
|
||||||
"@types/lodash": "^4.14.184",
|
"@types/lodash": "^4.14.184",
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import { Spinner } from '@wordpress/components';
|
||||||
|
import { useDebounce } from '@wordpress/compose';
|
||||||
|
import { useCallback, useState, createElement } from '@wordpress/element';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import { SelectControlProps } from '../select-control';
|
||||||
|
import { SuffixIcon } from '../suffix-icon';
|
||||||
|
|
||||||
|
export const DEFAULT_DEBOUNCE_TIME = 250;
|
||||||
|
|
||||||
|
export default function useAsyncFilter< T >( {
|
||||||
|
filter,
|
||||||
|
onFilterStart,
|
||||||
|
onFilterEnd,
|
||||||
|
onFilterError,
|
||||||
|
debounceTime,
|
||||||
|
}: UseAsyncFilterInput< T > ): UseAsyncFilterOutput< T > {
|
||||||
|
const [ isFetching, setIsFetching ] = useState( false );
|
||||||
|
|
||||||
|
const handleInputChange = useCallback(
|
||||||
|
function handleInputChangeCallback( value?: string ) {
|
||||||
|
if ( typeof filter === 'function' ) {
|
||||||
|
if ( typeof onFilterStart === 'function' )
|
||||||
|
onFilterStart( value );
|
||||||
|
|
||||||
|
setIsFetching( true );
|
||||||
|
|
||||||
|
filter( value )
|
||||||
|
.then( ( filteredItems ) => {
|
||||||
|
if ( typeof onFilterEnd === 'function' )
|
||||||
|
onFilterEnd( filteredItems, value );
|
||||||
|
} )
|
||||||
|
.catch( ( error: Error ) => {
|
||||||
|
if ( typeof onFilterError === 'function' )
|
||||||
|
onFilterError( error, value );
|
||||||
|
} )
|
||||||
|
.finally( () => {
|
||||||
|
setIsFetching( false );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[ filter, onFilterStart, onFilterEnd, onFilterError ]
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
isFetching,
|
||||||
|
suffix:
|
||||||
|
isFetching === true ? (
|
||||||
|
<SuffixIcon icon={ <Spinner /> } />
|
||||||
|
) : undefined,
|
||||||
|
getFilteredItems: ( items ) => items,
|
||||||
|
onInputChange: useDebounce(
|
||||||
|
handleInputChange,
|
||||||
|
typeof debounceTime === 'number'
|
||||||
|
? debounceTime
|
||||||
|
: DEFAULT_DEBOUNCE_TIME
|
||||||
|
),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export type UseAsyncFilterInput< T > = {
|
||||||
|
filter( value?: string ): Promise< T[] >;
|
||||||
|
onFilterStart?( value?: string ): void;
|
||||||
|
onFilterEnd?( filteredItems: T[], value?: string ): void;
|
||||||
|
onFilterError?( error: Error, value?: string ): void;
|
||||||
|
debounceTime?: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type UseAsyncFilterOutput< T > = Pick<
|
||||||
|
SelectControlProps< T >,
|
||||||
|
'suffix' | 'onInputChange' | 'getFilteredItems'
|
||||||
|
> & {
|
||||||
|
isFetching: boolean;
|
||||||
|
};
|
|
@ -1 +1,2 @@
|
||||||
export * from './select-control';
|
export * from './select-control';
|
||||||
|
export { default as useAsyncFilter } from './hooks/use-async-filter';
|
||||||
|
|
|
@ -36,7 +36,7 @@ import {
|
||||||
defaultGetFilteredItems,
|
defaultGetFilteredItems,
|
||||||
} from './utils';
|
} from './utils';
|
||||||
|
|
||||||
type SelectControlProps< ItemType > = {
|
export type SelectControlProps< ItemType > = {
|
||||||
children?: ChildrenType< ItemType >;
|
children?: ChildrenType< ItemType >;
|
||||||
items: ItemType[];
|
items: ItemType[];
|
||||||
label: string | JSX.Element;
|
label: string | JSX.Element;
|
||||||
|
|
|
@ -8,7 +8,7 @@ import {
|
||||||
SlotFillProvider,
|
SlotFillProvider,
|
||||||
Spinner,
|
Spinner,
|
||||||
} from '@wordpress/components';
|
} from '@wordpress/components';
|
||||||
import React from 'react';
|
import React, { useCallback } from 'react';
|
||||||
import { createElement, useState } from '@wordpress/element';
|
import { createElement, useState } from '@wordpress/element';
|
||||||
import { tag } from '@wordpress/icons';
|
import { tag } from '@wordpress/icons';
|
||||||
|
|
||||||
|
@ -17,11 +17,15 @@ import { tag } from '@wordpress/icons';
|
||||||
*/
|
*/
|
||||||
import { SelectedType, DefaultItemType, getItemLabelType } from '../types';
|
import { SelectedType, DefaultItemType, getItemLabelType } from '../types';
|
||||||
import { MenuItem } from '../menu-item';
|
import { MenuItem } from '../menu-item';
|
||||||
import { SelectControl, selectControlStateChangeTypes } from '../';
|
import {
|
||||||
|
SelectControl,
|
||||||
|
selectControlStateChangeTypes,
|
||||||
|
useAsyncFilter,
|
||||||
|
} from '../';
|
||||||
import { Menu, MenuSlot } from '../menu';
|
import { Menu, MenuSlot } from '../menu';
|
||||||
import { SuffixIcon } from '../suffix-icon';
|
import { SuffixIcon } from '../suffix-icon';
|
||||||
|
|
||||||
const sampleItems = [
|
const sampleItems: DefaultItemType[] = [
|
||||||
{ value: 'apple', label: 'Apple' },
|
{ value: 'apple', label: 'Apple' },
|
||||||
{ value: 'pear', label: 'Pear' },
|
{ value: 'pear', label: 'Pear' },
|
||||||
{ value: 'orange', label: 'Orange' },
|
{ value: 'orange', label: 'Orange' },
|
||||||
|
@ -133,35 +137,121 @@ export const FuzzyMatching: React.FC = () => {
|
||||||
|
|
||||||
export const Async: React.FC = () => {
|
export const Async: React.FC = () => {
|
||||||
const [ selectedItem, setSelectedItem ] =
|
const [ selectedItem, setSelectedItem ] =
|
||||||
useState< SelectedType< DefaultItemType > >( null );
|
useState< DefaultItemType | null >( null );
|
||||||
const [ fetchedItems, setFetchedItems ] = useState< DefaultItemType[] >(
|
const [ fetchedItems, setFetchedItems ] = useState< DefaultItemType[] >(
|
||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
const [ isFetching, setIsFetching ] = useState( false );
|
|
||||||
|
|
||||||
const fetchItems = ( value: string | undefined ) => {
|
const filter = useCallback(
|
||||||
setIsFetching( true );
|
( value = '' ) =>
|
||||||
setFetchedItems( [] );
|
new Promise< DefaultItemType[] >( ( resolve ) => {
|
||||||
setTimeout( () => {
|
setTimeout( () => {
|
||||||
const results = sampleItems.sort( () => 0.5 - Math.random() );
|
const filteredItems = [ ...sampleItems ]
|
||||||
setFetchedItems( results );
|
.sort( ( a, b ) => a.label.localeCompare( b.label ) )
|
||||||
setIsFetching( false );
|
.filter( ( { label } ) =>
|
||||||
}, 1500 );
|
label.toLowerCase().includes( value.toLowerCase() )
|
||||||
};
|
);
|
||||||
|
resolve( filteredItems );
|
||||||
|
}, 1500 );
|
||||||
|
} ),
|
||||||
|
[ selectedItem ]
|
||||||
|
);
|
||||||
|
|
||||||
|
const { isFetching, ...selectProps } = useAsyncFilter< DefaultItemType >( {
|
||||||
|
filter,
|
||||||
|
onFilterStart() {
|
||||||
|
setFetchedItems( [] );
|
||||||
|
},
|
||||||
|
onFilterEnd( filteredItems ) {
|
||||||
|
setFetchedItems( filteredItems );
|
||||||
|
},
|
||||||
|
} );
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<SelectControl
|
<SelectControl< DefaultItemType >
|
||||||
|
{ ...selectProps }
|
||||||
label="Async"
|
label="Async"
|
||||||
getFilteredItems={ ( allItems ) => {
|
|
||||||
return allItems;
|
|
||||||
} }
|
|
||||||
items={ fetchedItems }
|
items={ fetchedItems }
|
||||||
onInputChange={ fetchItems }
|
|
||||||
selected={ selectedItem }
|
selected={ selectedItem }
|
||||||
onSelect={ ( item ) => setSelectedItem( item ) }
|
|
||||||
onRemove={ () => setSelectedItem( null ) }
|
|
||||||
placeholder="Start typing..."
|
placeholder="Start typing..."
|
||||||
|
onSelect={ setSelectedItem }
|
||||||
|
onRemove={ () => setSelectedItem( null ) }
|
||||||
|
>
|
||||||
|
{ ( {
|
||||||
|
items,
|
||||||
|
isOpen,
|
||||||
|
highlightedIndex,
|
||||||
|
getItemProps,
|
||||||
|
getMenuProps,
|
||||||
|
} ) => {
|
||||||
|
return (
|
||||||
|
<Menu isOpen={ isOpen } getMenuProps={ getMenuProps }>
|
||||||
|
{ isFetching ? (
|
||||||
|
<Spinner />
|
||||||
|
) : (
|
||||||
|
items.map( ( item, index: number ) => (
|
||||||
|
<MenuItem
|
||||||
|
key={ `${ item.value }${ index }` }
|
||||||
|
index={ index }
|
||||||
|
isActive={ highlightedIndex === index }
|
||||||
|
item={ item }
|
||||||
|
getItemProps={ getItemProps }
|
||||||
|
>
|
||||||
|
{ item.label }
|
||||||
|
</MenuItem>
|
||||||
|
) )
|
||||||
|
) }
|
||||||
|
</Menu>
|
||||||
|
);
|
||||||
|
} }
|
||||||
|
</SelectControl>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const AsyncWithoutListeningFilterEvents: React.FC = () => {
|
||||||
|
const [ selectedItem, setSelectedItem ] =
|
||||||
|
useState< DefaultItemType | null >( null );
|
||||||
|
const [ fetchedItems, setFetchedItems ] = useState< DefaultItemType[] >(
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
|
const filter = useCallback(
|
||||||
|
async ( value = '' ) => {
|
||||||
|
setFetchedItems( [] );
|
||||||
|
return new Promise< DefaultItemType[] >( ( resolve ) => {
|
||||||
|
setTimeout( () => {
|
||||||
|
const filteredItems = [ ...sampleItems ]
|
||||||
|
.sort( ( a, b ) => a.label.localeCompare( b.label ) )
|
||||||
|
.filter( ( { label } ) =>
|
||||||
|
label.toLowerCase().includes( value.toLowerCase() )
|
||||||
|
);
|
||||||
|
|
||||||
|
resolve( filteredItems );
|
||||||
|
}, 1500 );
|
||||||
|
} ).then( ( filteredItems ) => {
|
||||||
|
setFetchedItems( filteredItems );
|
||||||
|
return filteredItems;
|
||||||
|
} );
|
||||||
|
},
|
||||||
|
[ selectedItem ]
|
||||||
|
);
|
||||||
|
|
||||||
|
const { isFetching, ...selectProps } = useAsyncFilter< DefaultItemType >( {
|
||||||
|
filter,
|
||||||
|
} );
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<SelectControl< DefaultItemType >
|
||||||
|
{ ...selectProps }
|
||||||
|
label="Async"
|
||||||
|
items={ fetchedItems }
|
||||||
|
selected={ selectedItem }
|
||||||
|
placeholder="Start typing..."
|
||||||
|
onSelect={ setSelectedItem }
|
||||||
|
onRemove={ () => setSelectedItem( null ) }
|
||||||
>
|
>
|
||||||
{ ( {
|
{ ( {
|
||||||
items,
|
items,
|
||||||
|
|
|
@ -3,4 +3,8 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding-right: $gap-smaller;
|
padding-right: $gap-smaller;
|
||||||
|
|
||||||
|
.components-spinner {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,128 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import { act, renderHook } from '@testing-library/react-hooks';
|
||||||
|
import { useDebounce } from '@wordpress/compose';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import { useAsyncFilter } from '../';
|
||||||
|
|
||||||
|
jest.mock( '@wordpress/compose', () => ( {
|
||||||
|
...jest.requireActual( '@wordpress/compose' ),
|
||||||
|
useDebounce: jest.fn( ( cb: CallableFunction ) => cb ),
|
||||||
|
} ) );
|
||||||
|
|
||||||
|
describe( 'useAsyncFilter', () => {
|
||||||
|
const filter = jest.fn();
|
||||||
|
const onFilterStart = jest.fn();
|
||||||
|
const onFilterEnd = jest.fn();
|
||||||
|
const onFilterError = jest.fn();
|
||||||
|
|
||||||
|
afterEach( () => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
} );
|
||||||
|
|
||||||
|
it( 'should filter the items successfully', async () => {
|
||||||
|
const filteredItems: string[] = [];
|
||||||
|
|
||||||
|
filter.mockResolvedValue( filteredItems );
|
||||||
|
|
||||||
|
const { result } = renderHook( () =>
|
||||||
|
useAsyncFilter( {
|
||||||
|
filter,
|
||||||
|
} )
|
||||||
|
);
|
||||||
|
|
||||||
|
const inputValue = 'Apple';
|
||||||
|
|
||||||
|
await act( async () => {
|
||||||
|
if ( result.current.onInputChange )
|
||||||
|
result.current.onInputChange( inputValue, {} );
|
||||||
|
} );
|
||||||
|
|
||||||
|
expect( useDebounce ).toHaveBeenCalledWith(
|
||||||
|
expect.any( Function ),
|
||||||
|
250
|
||||||
|
);
|
||||||
|
expect( filter ).toHaveBeenCalledWith( inputValue );
|
||||||
|
} );
|
||||||
|
|
||||||
|
it( 'should trigger onFilterStart at the begining of the filtering', async () => {
|
||||||
|
const filteredItems: string[] = [];
|
||||||
|
|
||||||
|
onFilterStart.mockImplementation( ( value = '' ) => {
|
||||||
|
expect( filter ).not.toHaveBeenCalledWith( value );
|
||||||
|
} );
|
||||||
|
|
||||||
|
filter.mockImplementation( ( value = '' ) => {
|
||||||
|
expect( onFilterStart ).toHaveBeenCalledWith( value );
|
||||||
|
return Promise.resolve( filteredItems );
|
||||||
|
} );
|
||||||
|
|
||||||
|
const { result } = renderHook( () =>
|
||||||
|
useAsyncFilter( {
|
||||||
|
filter,
|
||||||
|
onFilterStart,
|
||||||
|
} )
|
||||||
|
);
|
||||||
|
|
||||||
|
const inputValue = 'Apple';
|
||||||
|
|
||||||
|
await act( async () => {
|
||||||
|
if ( result.current.onInputChange )
|
||||||
|
result.current.onInputChange( inputValue, {} );
|
||||||
|
} );
|
||||||
|
|
||||||
|
expect( filter ).toHaveBeenCalledWith( inputValue );
|
||||||
|
} );
|
||||||
|
|
||||||
|
it( 'should trigger onFilterEnd when filtering is fullfiled', async () => {
|
||||||
|
const filteredItems: string[] = [];
|
||||||
|
|
||||||
|
filter.mockResolvedValue( filteredItems );
|
||||||
|
|
||||||
|
const { result } = renderHook( () =>
|
||||||
|
useAsyncFilter( {
|
||||||
|
filter,
|
||||||
|
onFilterEnd,
|
||||||
|
onFilterError,
|
||||||
|
} )
|
||||||
|
);
|
||||||
|
|
||||||
|
const inputValue = 'Apple';
|
||||||
|
|
||||||
|
await act( async () => {
|
||||||
|
if ( result.current.onInputChange )
|
||||||
|
result.current.onInputChange( inputValue, {} );
|
||||||
|
} );
|
||||||
|
|
||||||
|
expect( onFilterEnd ).toHaveBeenCalledWith( filteredItems, inputValue );
|
||||||
|
expect( onFilterError ).not.toHaveBeenCalled();
|
||||||
|
} );
|
||||||
|
|
||||||
|
it( 'should trigger onFilterError when filtering is rejected', async () => {
|
||||||
|
const error = new Error();
|
||||||
|
|
||||||
|
filter.mockRejectedValue( error );
|
||||||
|
|
||||||
|
const { result } = renderHook( () =>
|
||||||
|
useAsyncFilter( {
|
||||||
|
filter,
|
||||||
|
onFilterEnd,
|
||||||
|
onFilterError,
|
||||||
|
} )
|
||||||
|
);
|
||||||
|
|
||||||
|
const inputValue = 'Apple';
|
||||||
|
|
||||||
|
await act( async () => {
|
||||||
|
if ( result.current.onInputChange )
|
||||||
|
result.current.onInputChange( inputValue, {} );
|
||||||
|
} );
|
||||||
|
|
||||||
|
expect( onFilterEnd ).not.toHaveBeenCalled();
|
||||||
|
expect( onFilterError ).toHaveBeenCalledWith( error, inputValue );
|
||||||
|
} );
|
||||||
|
} );
|
|
@ -45,6 +45,7 @@ export { default as SelectControl } from './select-control';
|
||||||
export {
|
export {
|
||||||
SelectControl as __experimentalSelectControl,
|
SelectControl as __experimentalSelectControl,
|
||||||
selectControlStateChangeTypes,
|
selectControlStateChangeTypes,
|
||||||
|
useAsyncFilter,
|
||||||
} from './experimental-select-control';
|
} from './experimental-select-control';
|
||||||
export {
|
export {
|
||||||
MenuItem as __experimentalSelectControlMenuItem,
|
MenuItem as __experimentalSelectControlMenuItem,
|
||||||
|
|
126
pnpm-lock.yaml
126
pnpm-lock.yaml
|
@ -200,6 +200,7 @@ importers:
|
||||||
'@testing-library/dom': ^8.11.3
|
'@testing-library/dom': ^8.11.3
|
||||||
'@testing-library/jest-dom': ^5.16.2
|
'@testing-library/jest-dom': ^5.16.2
|
||||||
'@testing-library/react': ^12.1.3
|
'@testing-library/react': ^12.1.3
|
||||||
|
'@testing-library/react-hooks': ^8.0.1
|
||||||
'@testing-library/user-event': ^13.5.0
|
'@testing-library/user-event': ^13.5.0
|
||||||
'@types/jest': ^27.4.1
|
'@types/jest': ^27.4.1
|
||||||
'@types/lodash': ^4.14.184
|
'@types/lodash': ^4.14.184
|
||||||
|
@ -355,6 +356,7 @@ importers:
|
||||||
'@testing-library/dom': 8.11.3
|
'@testing-library/dom': 8.11.3
|
||||||
'@testing-library/jest-dom': 5.16.2
|
'@testing-library/jest-dom': 5.16.2
|
||||||
'@testing-library/react': 12.1.4_sfoxds7t5ydpegc3knd667wn6m
|
'@testing-library/react': 12.1.4_sfoxds7t5ydpegc3knd667wn6m
|
||||||
|
'@testing-library/react-hooks': 8.0.1_hiunvzosbwliizyirxfy6hjyim
|
||||||
'@testing-library/user-event': 13.5.0_gzufz4q333be4gqfrvipwvqt6a
|
'@testing-library/user-event': 13.5.0_gzufz4q333be4gqfrvipwvqt6a
|
||||||
'@types/jest': 27.4.1
|
'@types/jest': 27.4.1
|
||||||
'@types/lodash': 4.14.184
|
'@types/lodash': 4.14.184
|
||||||
|
@ -2932,6 +2934,42 @@ packages:
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@babel/helper-define-polyfill-provider/0.3.0_@babel+core@7.16.12:
|
||||||
|
resolution: {integrity: sha512-7hfT8lUljl/tM3h+izTX/pO3W3frz2ok6Pk+gzys8iJqDfZrZy2pXjRTZAvG2YmfHun1X4q8/UZRLatMfqc5Tg==}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.4.0-0
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.16.12
|
||||||
|
'@babel/helper-compilation-targets': 7.19.3_@babel+core@7.16.12
|
||||||
|
'@babel/helper-module-imports': 7.18.6
|
||||||
|
'@babel/helper-plugin-utils': 7.19.0
|
||||||
|
'@babel/traverse': 7.19.3
|
||||||
|
debug: 4.3.4
|
||||||
|
lodash.debounce: 4.0.8
|
||||||
|
resolve: 1.22.1
|
||||||
|
semver: 6.3.0
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@babel/helper-define-polyfill-provider/0.3.0_@babel+core@7.17.8:
|
||||||
|
resolution: {integrity: sha512-7hfT8lUljl/tM3h+izTX/pO3W3frz2ok6Pk+gzys8iJqDfZrZy2pXjRTZAvG2YmfHun1X4q8/UZRLatMfqc5Tg==}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.4.0-0
|
||||||
|
dependencies:
|
||||||
|
'@babel/core': 7.17.8
|
||||||
|
'@babel/helper-compilation-targets': 7.19.3_@babel+core@7.17.8
|
||||||
|
'@babel/helper-module-imports': 7.18.6
|
||||||
|
'@babel/helper-plugin-utils': 7.19.0
|
||||||
|
'@babel/traverse': 7.19.3
|
||||||
|
debug: 4.3.4
|
||||||
|
lodash.debounce: 4.0.8
|
||||||
|
resolve: 1.22.1
|
||||||
|
semver: 6.3.0
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@babel/helper-define-polyfill-provider/0.3.1_@babel+core@7.12.9:
|
/@babel/helper-define-polyfill-provider/0.3.1_@babel+core@7.12.9:
|
||||||
resolution: {integrity: sha512-J9hGMpJQmtWmj46B3kBHmL38UhJGhYX7eqkcq+2gsstyYt341HmPeWspihX43yVRA0mS+8GGk2Gckc7bY/HCmA==}
|
resolution: {integrity: sha512-J9hGMpJQmtWmj46B3kBHmL38UhJGhYX7eqkcq+2gsstyYt341HmPeWspihX43yVRA0mS+8GGk2Gckc7bY/HCmA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
@ -3576,8 +3614,8 @@ packages:
|
||||||
'@babel/core': ^7.0.0-0
|
'@babel/core': ^7.0.0-0
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/core': 7.12.9
|
'@babel/core': 7.12.9
|
||||||
'@babel/helper-create-class-features-plugin': 7.17.6_@babel+core@7.12.9
|
'@babel/helper-create-class-features-plugin': 7.19.0_@babel+core@7.12.9
|
||||||
'@babel/helper-plugin-utils': 7.18.9
|
'@babel/helper-plugin-utils': 7.19.0
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
@ -3589,8 +3627,8 @@ packages:
|
||||||
'@babel/core': ^7.0.0-0
|
'@babel/core': ^7.0.0-0
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/core': 7.16.12
|
'@babel/core': 7.16.12
|
||||||
'@babel/helper-create-class-features-plugin': 7.17.6_@babel+core@7.16.12
|
'@babel/helper-create-class-features-plugin': 7.19.0_@babel+core@7.16.12
|
||||||
'@babel/helper-plugin-utils': 7.18.9
|
'@babel/helper-plugin-utils': 7.19.0
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: false
|
dev: false
|
||||||
|
@ -6540,9 +6578,9 @@ packages:
|
||||||
'@babel/core': ^7.0.0-0
|
'@babel/core': ^7.0.0-0
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/core': 7.16.12
|
'@babel/core': 7.16.12
|
||||||
'@babel/helper-module-imports': 7.16.0
|
'@babel/helper-module-imports': 7.18.6
|
||||||
'@babel/helper-plugin-utils': 7.14.5
|
'@babel/helper-plugin-utils': 7.19.0
|
||||||
babel-plugin-polyfill-corejs2: 0.3.0_@babel+core@7.16.12
|
babel-plugin-polyfill-corejs2: 0.3.3_@babel+core@7.16.12
|
||||||
babel-plugin-polyfill-corejs3: 0.4.0_@babel+core@7.16.12
|
babel-plugin-polyfill-corejs3: 0.4.0_@babel+core@7.16.12
|
||||||
babel-plugin-polyfill-regenerator: 0.3.0_@babel+core@7.16.12
|
babel-plugin-polyfill-regenerator: 0.3.0_@babel+core@7.16.12
|
||||||
semver: 6.3.0
|
semver: 6.3.0
|
||||||
|
@ -6557,9 +6595,9 @@ packages:
|
||||||
'@babel/core': ^7.0.0-0
|
'@babel/core': ^7.0.0-0
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/core': 7.17.8
|
'@babel/core': 7.17.8
|
||||||
'@babel/helper-module-imports': 7.16.0
|
'@babel/helper-module-imports': 7.18.6
|
||||||
'@babel/helper-plugin-utils': 7.14.5
|
'@babel/helper-plugin-utils': 7.19.0
|
||||||
babel-plugin-polyfill-corejs2: 0.3.0_@babel+core@7.17.8
|
babel-plugin-polyfill-corejs2: 0.3.3_@babel+core@7.17.8
|
||||||
babel-plugin-polyfill-corejs3: 0.4.0_@babel+core@7.17.8
|
babel-plugin-polyfill-corejs3: 0.4.0_@babel+core@7.17.8
|
||||||
babel-plugin-polyfill-regenerator: 0.3.0_@babel+core@7.17.8
|
babel-plugin-polyfill-regenerator: 0.3.0_@babel+core@7.17.8
|
||||||
semver: 6.3.0
|
semver: 6.3.0
|
||||||
|
@ -6650,8 +6688,8 @@ packages:
|
||||||
'@babel/core': ^7.0.0-0
|
'@babel/core': ^7.0.0-0
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/core': 7.12.9
|
'@babel/core': 7.12.9
|
||||||
'@babel/helper-plugin-utils': 7.18.9
|
'@babel/helper-plugin-utils': 7.19.0
|
||||||
'@babel/helper-skip-transparent-expression-wrappers': 7.16.0
|
'@babel/helper-skip-transparent-expression-wrappers': 7.18.9
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@babel/plugin-transform-spread/7.16.7_@babel+core@7.16.12:
|
/@babel/plugin-transform-spread/7.16.7_@babel+core@7.16.12:
|
||||||
|
@ -6661,8 +6699,8 @@ packages:
|
||||||
'@babel/core': ^7.0.0-0
|
'@babel/core': ^7.0.0-0
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/core': 7.16.12
|
'@babel/core': 7.16.12
|
||||||
'@babel/helper-plugin-utils': 7.18.9
|
'@babel/helper-plugin-utils': 7.19.0
|
||||||
'@babel/helper-skip-transparent-expression-wrappers': 7.16.0
|
'@babel/helper-skip-transparent-expression-wrappers': 7.18.9
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@babel/plugin-transform-spread/7.16.7_@babel+core@7.17.8:
|
/@babel/plugin-transform-spread/7.16.7_@babel+core@7.17.8:
|
||||||
|
@ -6840,7 +6878,7 @@ packages:
|
||||||
'@babel/core': ^7.0.0-0
|
'@babel/core': ^7.0.0-0
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/core': 7.16.12
|
'@babel/core': 7.16.12
|
||||||
'@babel/helper-create-class-features-plugin': 7.17.6_@babel+core@7.16.12
|
'@babel/helper-create-class-features-plugin': 7.19.0_@babel+core@7.16.12
|
||||||
'@babel/helper-plugin-utils': 7.19.0
|
'@babel/helper-plugin-utils': 7.19.0
|
||||||
'@babel/plugin-syntax-typescript': 7.16.7_@babel+core@7.16.12
|
'@babel/plugin-syntax-typescript': 7.16.7_@babel+core@7.16.12
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
@ -7471,8 +7509,8 @@ packages:
|
||||||
'@babel/core': ^7.0.0-0
|
'@babel/core': ^7.0.0-0
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/core': 7.16.12
|
'@babel/core': 7.16.12
|
||||||
'@babel/helper-plugin-utils': 7.18.9
|
'@babel/helper-plugin-utils': 7.19.0
|
||||||
'@babel/helper-validator-option': 7.16.7
|
'@babel/helper-validator-option': 7.18.6
|
||||||
'@babel/plugin-transform-typescript': 7.16.8_@babel+core@7.16.12
|
'@babel/plugin-transform-typescript': 7.16.8_@babel+core@7.16.12
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
@ -13300,6 +13338,29 @@ packages:
|
||||||
react-error-boundary: 3.1.4_react@17.0.2
|
react-error-boundary: 3.1.4_react@17.0.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@testing-library/react-hooks/8.0.1_hiunvzosbwliizyirxfy6hjyim:
|
||||||
|
resolution: {integrity: sha512-Aqhl2IVmLt8IovEVarNDFuJDVWVvhnr9/GCU6UUnrYXwgDFF9h2L2o2P9KBni1AST5sT6riAyoukFLyjQUgD/g==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
peerDependencies:
|
||||||
|
'@types/react': ^16.9.0 || ^17.0.0
|
||||||
|
react: ^16.9.0 || ^17.0.0
|
||||||
|
react-dom: ^16.9.0 || ^17.0.0
|
||||||
|
react-test-renderer: ^16.9.0 || ^17.0.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/react':
|
||||||
|
optional: true
|
||||||
|
react-dom:
|
||||||
|
optional: true
|
||||||
|
react-test-renderer:
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.19.0
|
||||||
|
'@types/react': 17.0.50
|
||||||
|
react: 17.0.2
|
||||||
|
react-dom: 17.0.2_react@17.0.2
|
||||||
|
react-error-boundary: 3.1.4_react@17.0.2
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@testing-library/react/12.1.4_sfoxds7t5ydpegc3knd667wn6m:
|
/@testing-library/react/12.1.4_sfoxds7t5ydpegc3knd667wn6m:
|
||||||
resolution: {integrity: sha512-jiPKOm7vyUw311Hn/HlNQ9P8/lHNtArAx0PisXyFixDDvfl8DbD6EUdbshK5eqauvBSvzZd19itqQ9j3nferJA==}
|
resolution: {integrity: sha512-jiPKOm7vyUw311Hn/HlNQ9P8/lHNtArAx0PisXyFixDDvfl8DbD6EUdbshK5eqauvBSvzZd19itqQ9j3nferJA==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
|
@ -19127,6 +19188,19 @@ packages:
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/babel-plugin-polyfill-corejs2/0.3.3_@babel+core@7.16.12:
|
||||||
|
resolution: {integrity: sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==}
|
||||||
|
peerDependencies:
|
||||||
|
'@babel/core': ^7.0.0-0
|
||||||
|
dependencies:
|
||||||
|
'@babel/compat-data': 7.19.3
|
||||||
|
'@babel/core': 7.16.12
|
||||||
|
'@babel/helper-define-polyfill-provider': 0.3.3_@babel+core@7.16.12
|
||||||
|
semver: 6.3.0
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
dev: false
|
||||||
|
|
||||||
/babel-plugin-polyfill-corejs2/0.3.3_@babel+core@7.17.8:
|
/babel-plugin-polyfill-corejs2/0.3.3_@babel+core@7.17.8:
|
||||||
resolution: {integrity: sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==}
|
resolution: {integrity: sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
@ -19169,7 +19243,7 @@ packages:
|
||||||
'@babel/core': ^7.0.0-0
|
'@babel/core': ^7.0.0-0
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/core': 7.16.12
|
'@babel/core': 7.16.12
|
||||||
'@babel/helper-define-polyfill-provider': 0.3.3_@babel+core@7.16.12
|
'@babel/helper-define-polyfill-provider': 0.3.0_@babel+core@7.16.12
|
||||||
core-js-compat: 3.25.5
|
core-js-compat: 3.25.5
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
@ -19181,7 +19255,7 @@ packages:
|
||||||
'@babel/core': ^7.0.0-0
|
'@babel/core': ^7.0.0-0
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/core': 7.17.8
|
'@babel/core': 7.17.8
|
||||||
'@babel/helper-define-polyfill-provider': 0.3.3_@babel+core@7.17.8
|
'@babel/helper-define-polyfill-provider': 0.3.0_@babel+core@7.17.8
|
||||||
core-js-compat: 3.25.5
|
core-js-compat: 3.25.5
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
@ -24004,7 +24078,7 @@ packages:
|
||||||
file-entry-cache: 6.0.1
|
file-entry-cache: 6.0.1
|
||||||
functional-red-black-tree: 1.0.1
|
functional-red-black-tree: 1.0.1
|
||||||
glob-parent: 5.1.2
|
glob-parent: 5.1.2
|
||||||
globals: 13.17.0
|
globals: 13.18.0
|
||||||
ignore: 4.0.6
|
ignore: 4.0.6
|
||||||
import-fresh: 3.3.0
|
import-fresh: 3.3.0
|
||||||
imurmurhash: 0.1.4
|
imurmurhash: 0.1.4
|
||||||
|
@ -25327,7 +25401,7 @@ packages:
|
||||||
vue-template-compiler:
|
vue-template-compiler:
|
||||||
optional: true
|
optional: true
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/code-frame': 7.16.7
|
'@babel/code-frame': 7.18.6
|
||||||
'@types/json-schema': 7.0.9
|
'@types/json-schema': 7.0.9
|
||||||
chalk: 4.1.2
|
chalk: 4.1.2
|
||||||
chokidar: 3.5.3
|
chokidar: 3.5.3
|
||||||
|
@ -25338,7 +25412,7 @@ packages:
|
||||||
memfs: 3.3.0
|
memfs: 3.3.0
|
||||||
minimatch: 3.1.2
|
minimatch: 3.1.2
|
||||||
schema-utils: 2.7.0
|
schema-utils: 2.7.0
|
||||||
semver: 7.3.5
|
semver: 7.3.8
|
||||||
tapable: 1.1.3
|
tapable: 1.1.3
|
||||||
typescript: 4.8.4
|
typescript: 4.8.4
|
||||||
webpack: 5.70.0
|
webpack: 5.70.0
|
||||||
|
@ -25358,7 +25432,7 @@ packages:
|
||||||
vue-template-compiler:
|
vue-template-compiler:
|
||||||
optional: true
|
optional: true
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/code-frame': 7.16.7
|
'@babel/code-frame': 7.18.6
|
||||||
'@types/json-schema': 7.0.9
|
'@types/json-schema': 7.0.9
|
||||||
chalk: 4.1.2
|
chalk: 4.1.2
|
||||||
chokidar: 3.5.3
|
chokidar: 3.5.3
|
||||||
|
@ -25370,7 +25444,7 @@ packages:
|
||||||
memfs: 3.3.0
|
memfs: 3.3.0
|
||||||
minimatch: 3.1.2
|
minimatch: 3.1.2
|
||||||
schema-utils: 2.7.0
|
schema-utils: 2.7.0
|
||||||
semver: 7.3.5
|
semver: 7.3.8
|
||||||
tapable: 1.1.3
|
tapable: 1.1.3
|
||||||
typescript: 4.8.4
|
typescript: 4.8.4
|
||||||
webpack: 4.46.0_webpack-cli@3.3.12
|
webpack: 4.46.0_webpack-cli@3.3.12
|
||||||
|
@ -25422,7 +25496,7 @@ packages:
|
||||||
vue-template-compiler:
|
vue-template-compiler:
|
||||||
optional: true
|
optional: true
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/code-frame': 7.16.7
|
'@babel/code-frame': 7.18.6
|
||||||
'@types/json-schema': 7.0.9
|
'@types/json-schema': 7.0.9
|
||||||
chalk: 4.1.2
|
chalk: 4.1.2
|
||||||
chokidar: 3.5.3
|
chokidar: 3.5.3
|
||||||
|
@ -25433,7 +25507,7 @@ packages:
|
||||||
memfs: 3.3.0
|
memfs: 3.3.0
|
||||||
minimatch: 3.1.2
|
minimatch: 3.1.2
|
||||||
schema-utils: 2.7.0
|
schema-utils: 2.7.0
|
||||||
semver: 7.3.5
|
semver: 7.3.8
|
||||||
tapable: 1.1.3
|
tapable: 1.1.3
|
||||||
typescript: 4.8.4
|
typescript: 4.8.4
|
||||||
webpack: 4.46.0
|
webpack: 4.46.0
|
||||||
|
|
Loading…
Reference in New Issue