diff --git a/packages/peregrine/lib/talons/FilterModal/__tests__/useFilterModal.spec.js b/packages/peregrine/lib/talons/FilterModal/__tests__/useFilterModal.spec.js index 706ad2be31..6157053688 100644 --- a/packages/peregrine/lib/talons/FilterModal/__tests__/useFilterModal.spec.js +++ b/packages/peregrine/lib/talons/FilterModal/__tests__/useFilterModal.spec.js @@ -131,6 +131,8 @@ describe('#useFilterModal', () => { filterState: expect.any(Object), handleApply: expect.any(Function), handleClose: expect.any(Function), + handleKeyDownActions: expect.any(Function), + handleOpen: expect.any(Function), handleReset: expect.any(Function), isApplying: expect.any(Boolean), isOpen: expect.any(Boolean) diff --git a/packages/peregrine/lib/talons/FilterModal/useFilterModal.js b/packages/peregrine/lib/talons/FilterModal/useFilterModal.js index 71b839ecf2..32459e1a6e 100644 --- a/packages/peregrine/lib/talons/FilterModal/useFilterModal.js +++ b/packages/peregrine/lib/talons/FilterModal/useFilterModal.js @@ -10,6 +10,8 @@ import { getSearchFromState, getStateFromSearch, stripHtml } from './helpers'; import DEFAULT_OPERATIONS from './filterModal.gql'; +const DRAWER_NAME = 'filter'; + /** * Filter Modal talon. * @@ -27,10 +29,10 @@ export const useFilterModal = props => { const { getFilterInputsQuery } = operations; const [isApplying, setIsApplying] = useState(false); - const [{ drawer }, { closeDrawer }] = useAppContext(); + const [{ drawer }, { toggleDrawer, closeDrawer }] = useAppContext(); const [filterState, filterApi] = useFilterState(); const prevDrawer = useRef(null); - const isOpen = drawer === 'filter'; + const isOpen = drawer === DRAWER_NAME; const history = useHistory(); const { pathname, search } = useLocation(); @@ -123,11 +125,48 @@ export const useFilterModal = props => { } }, [filterKeys, filterState, history, isApplying, pathname, search]); - // on drawer toggle, read filter state from location + const handleOpen = useCallback(() => { + toggleDrawer(DRAWER_NAME); + }, [toggleDrawer]); + + const handleClose = useCallback(() => { + closeDrawer(); + }, [closeDrawer]); + + const handleApply = useCallback(() => { + setIsApplying(true); + handleClose(); + }, [handleClose]); + + const handleReset = useCallback(() => { + filterApi.clear(); + setIsApplying(true); + }, [filterApi, setIsApplying]); + + const handleKeyDownActions = useCallback( + event => { + // do not handle keyboard actions when the modal is closed + if (!isOpen) { + return; + } + + switch (event.keyCode) { + // when "Esc" key fired -> close the modal + case 27: + handleClose(); + break; + } + }, + [isOpen, handleClose] + ); + useEffect(() => { - const justOpened = prevDrawer.current === null && drawer === 'filter'; - const justClosed = prevDrawer.current === 'filter' && drawer === null; + const justOpened = + prevDrawer.current === null && drawer === DRAWER_NAME; + const justClosed = + prevDrawer.current === DRAWER_NAME && drawer === null; + // on drawer toggle, read filter state from location if (justOpened || justClosed) { const nextState = getStateFromSearch( search, @@ -137,22 +176,14 @@ export const useFilterModal = props => { filterApi.setItems(nextState); } - prevDrawer.current = drawer; - }, [drawer, filterApi, filterItems, filterKeys, search]); - const handleApply = useCallback(() => { - setIsApplying(true); - closeDrawer(); - }, [closeDrawer]); - - const handleClose = useCallback(() => { - closeDrawer(); - }, [closeDrawer]); + // on drawer close, update the modal visibility state + if (justClosed) { + handleClose(); + } - const handleReset = useCallback(() => { - filterApi.clear(); - setIsApplying(true); - }, [filterApi, setIsApplying]); + prevDrawer.current = drawer; + }, [drawer, filterApi, filterItems, filterKeys, search, handleClose]); return { filterApi, @@ -162,6 +193,8 @@ export const useFilterModal = props => { filterState, handleApply, handleClose, + handleKeyDownActions, + handleOpen, handleReset, isApplying, isOpen diff --git a/packages/peregrine/lib/talons/RootComponents/Category/__tests__/__snapshots__/useCategoryContent.spec.js.snap b/packages/peregrine/lib/talons/RootComponents/Category/__tests__/__snapshots__/useCategoryContent.spec.js.snap index 9ccf94613f..a1f4d20f7c 100644 --- a/packages/peregrine/lib/talons/RootComponents/Category/__tests__/__snapshots__/useCategoryContent.spec.js.snap +++ b/packages/peregrine/lib/talons/RootComponents/Category/__tests__/__snapshots__/useCategoryContent.spec.js.snap @@ -2,11 +2,9 @@ exports[`handles no data prop 1`] = ` Object { - "categoryDescription": null, - "categoryName": null, + "categoryDescription": "Jewelry category", + "categoryName": "Jewelry", "filters": null, - "handleLoadFilters": [Function], - "handleOpenFilters": [Function], "items": Array [ null, null, @@ -18,7 +16,6 @@ Object { null, null, ], - "loadFilters": false, "totalPagesFromData": null, } `; @@ -32,8 +29,6 @@ Object { "label": "Label", }, ], - "handleLoadFilters": [Function], - "handleOpenFilters": [Function], "items": Array [ Object { "id": 1, @@ -44,7 +39,6 @@ Object { "name": "Necklace", }, ], - "loadFilters": false, "totalPagesFromData": 1, } `; diff --git a/packages/peregrine/lib/talons/RootComponents/Category/__tests__/useCategoryContent.spec.js b/packages/peregrine/lib/talons/RootComponents/Category/__tests__/useCategoryContent.spec.js index 2fccc69fd9..1f58650902 100644 --- a/packages/peregrine/lib/talons/RootComponents/Category/__tests__/useCategoryContent.spec.js +++ b/packages/peregrine/lib/talons/RootComponents/Category/__tests__/useCategoryContent.spec.js @@ -2,10 +2,7 @@ import React from 'react'; import { createTestInstance } from '@magento/peregrine'; import { useCategoryContent } from '../useCategoryContent'; -import { useLazyQuery } from '@apollo/client'; -import { act } from 'react-test-renderer'; - -import { useAppContext } from '../../../../context/app'; +import { useLazyQuery, useQuery } from '@apollo/client'; global.STORE_NAME = 'Venia'; @@ -23,7 +20,8 @@ jest.mock('@apollo/client', () => { const apolloClient = jest.requireActual('@apollo/client'); return { ...apolloClient, - useLazyQuery: jest.fn() + useLazyQuery: jest.fn(), + useQuery: jest.fn() }; }); const Component = props => { @@ -35,10 +33,6 @@ const Component = props => { const mockProps = { categoryId: 3, data: { - category: { - name: 'Jewelry', - description: 'Jewelry category' - }, products: { page_info: { total_pages: 1 @@ -66,6 +60,12 @@ const mockProductFiltersByCategoryData = { ] } }; +const mockCategoryData = { + category: { + name: 'Jewelry', + description: 'Jewelry category' + } +}; const mockGetFilters = jest.fn(); @@ -74,60 +74,18 @@ useLazyQuery.mockReturnValue([ { data: mockProductFiltersByCategoryData } ]); +useQuery.mockReturnValue({ data: mockCategoryData }); + it('returns the proper shape', () => { const rendered = createTestInstance(); const talonProps = rendered.root.findByType('i').props; expect(mockGetFilters).toHaveBeenCalled(); + expect(useQuery).toHaveBeenCalled(); expect(talonProps).toMatchSnapshot(); }); -it('sets the filter loading state', () => { - const rendered = createTestInstance(); - - const talonProps = rendered.root.findByType('i').props; - - const { loadFilters, handleLoadFilters } = talonProps; - - expect(loadFilters).toBeFalsy(); - - act(() => { - handleLoadFilters(); - }); - - const updatedProps = rendered.root.findByType('i').props; - - expect(updatedProps.loadFilters).toBeTruthy(); -}); - -it('toggles drawer when opening filters', () => { - const mockToggleDrawer = jest.fn(); - useAppContext.mockReturnValue([ - {}, - { - toggleDrawer: mockToggleDrawer - } - ]); - - const rendered = createTestInstance(); - - const talonProps = rendered.root.findByType('i').props; - - const { loadFilters, handleOpenFilters } = talonProps; - - expect(loadFilters).toBeFalsy(); - - act(() => { - handleOpenFilters(); - }); - - const updatedProps = rendered.root.findByType('i').props; - - expect(updatedProps.loadFilters).toBeTruthy(); - expect(mockToggleDrawer).toHaveBeenCalled(); -}); - it('handles default category id', () => { const testProps = Object.assign({}, mockProps, { categoryId: 0 @@ -153,6 +111,7 @@ it('handles no data prop', () => { data: null, pageSize: 9 }; + useLazyQuery.mockReturnValue([mockGetFilters, { data: null }]); const rendered = createTestInstance(); diff --git a/packages/peregrine/lib/talons/RootComponents/Category/categoryContent.gql.js b/packages/peregrine/lib/talons/RootComponents/Category/categoryContent.gql.js index d01e9eb2a2..378d86411a 100644 --- a/packages/peregrine/lib/talons/RootComponents/Category/categoryContent.gql.js +++ b/packages/peregrine/lib/talons/RootComponents/Category/categoryContent.gql.js @@ -18,6 +18,17 @@ export const GET_PRODUCT_FILTERS_BY_CATEGORY = gql` } `; +export const GET_CATEGORY_CONTENT = gql` + query getCategoryData($id: Int!) { + category(id: $id) { + id + name + description + } + } +`; + export default { + getCategoryContentQuery: GET_CATEGORY_CONTENT, getProductFiltersByCategoryQuery: GET_PRODUCT_FILTERS_BY_CATEGORY }; diff --git a/packages/peregrine/lib/talons/RootComponents/Category/categoryFragments.gql.js b/packages/peregrine/lib/talons/RootComponents/Category/categoryFragments.gql.js index 34e65fa6d1..2744ca0ccf 100644 --- a/packages/peregrine/lib/talons/RootComponents/Category/categoryFragments.gql.js +++ b/packages/peregrine/lib/talons/RootComponents/Category/categoryFragments.gql.js @@ -3,9 +3,6 @@ import { gql } from '@apollo/client'; export const CategoryFragment = gql` fragment CategoryFragment on CategoryTree { id - description - name - product_count meta_title meta_keywords meta_description diff --git a/packages/peregrine/lib/talons/RootComponents/Category/useCategoryContent.js b/packages/peregrine/lib/talons/RootComponents/Category/useCategoryContent.js index 5e43bf2b4e..98a514c8e5 100644 --- a/packages/peregrine/lib/talons/RootComponents/Category/useCategoryContent.js +++ b/packages/peregrine/lib/talons/RootComponents/Category/useCategoryContent.js @@ -1,44 +1,33 @@ -import { useCallback, useEffect, useState } from 'react'; -import { useLazyQuery } from '@apollo/client'; +import { useEffect } from 'react'; +import { useLazyQuery, useQuery } from '@apollo/client'; import mergeOperations from '../../../util/shallowMerge'; -import { useAppContext } from '../../../context/app'; import DEFAULT_OPERATIONS from './categoryContent.gql'; -const DRAWER_NAME = 'filter'; - /** * Returns props necessary to render the categoryContent component. * * @param {object} props.data - The results of a getCategory GraphQL query. * * @returns {object} result - * @returns {number} result.categoryId - This category's ID. + * @returns {string} result.categoryDescription - This category's description. * @returns {string} result.categoryName - This category's name. * @returns {object} result.filters - The filters object. - * @returns {func} result.handleLoadFilters - A callback function to signal the user's intent to interact with the filters. - * @returns {func} result.handleOpenFilters - A callback function that actually opens the filter drawer. * @returns {object} result.items - The items in this category. - * @returns {bool} result.loadFilters - Whether or not the user has signalled their intent to interact with the filters. + * @returns {number} result.totalPagesFromData - The total amount of pages for the query. */ export const useCategoryContent = props => { const { categoryId, data, pageSize = 6 } = props; const operations = mergeOperations(DEFAULT_OPERATIONS, props.operations); - const { getProductFiltersByCategoryQuery } = operations; - const placeholderItems = Array.from({ length: pageSize }).fill(null); - const [loadFilters, setLoadFilters] = useState(false); - const [, { toggleDrawer }] = useAppContext(); + const { + getCategoryContentQuery, + getProductFiltersByCategoryQuery + } = operations; - const handleLoadFilters = useCallback(() => { - setLoadFilters(true); - }, [setLoadFilters]); - const handleOpenFilters = useCallback(() => { - setLoadFilters(true); - toggleDrawer(DRAWER_NAME); - }, [setLoadFilters, toggleDrawer]); + const placeholderItems = Array.from({ length: pageSize }).fill(null); const [getFilters, { data: filterData }] = useLazyQuery( getProductFiltersByCategoryQuery, @@ -48,6 +37,15 @@ export const useCategoryContent = props => { } ); + const { data: categoryData } = useQuery(getCategoryContentQuery, { + fetchPolicy: 'cache-and-network', + nextFetchPolicy: 'cache-first', + skip: !categoryId, + variables: { + id: categoryId + } + }); + useEffect(() => { if (categoryId) { getFilters({ @@ -65,17 +63,16 @@ export const useCategoryContent = props => { const totalPagesFromData = data ? data.products.page_info.total_pages : null; - const categoryName = data ? data.category.name : null; - const categoryDescription = data ? data.category.description : null; + const categoryName = categoryData ? categoryData.category.name : null; + const categoryDescription = categoryData + ? categoryData.category.description + : null; return { categoryName, categoryDescription, filters, - handleLoadFilters, - handleOpenFilters, items, - loadFilters, totalPagesFromData }; }; diff --git a/packages/venia-ui/i18n/en_US.json b/packages/venia-ui/i18n/en_US.json index 15303a7de8..9ae2359afc 100644 --- a/packages/venia-ui/i18n/en_US.json +++ b/packages/venia-ui/i18n/en_US.json @@ -141,7 +141,17 @@ "field.optional": "Optional", "filterFooter.results": "See Results", "filterModal.action": "Clear all", + "filterModal.action.clearAll.ariaLabel": "Clear all applied filters", + "filterModal.action.clearFilterItem.ariaLabel": "Clear filter \"{name}\"", + "filterModal.currentFilters.ariaLabel": "Current Filters", + "filterModal.filters.ariaLabel": "Filters", + "filterModal.filters.close.ariaLabel": "Close filters popup.", "filterModal.headerTitle": "Filters", + "filterModal.item.applyFilter": "Apply filter \"{optionName}\".", + "filterModal.item.ariaLabel": "Filter products by \"{itemName}\"", + "filterModal.item.clearFilter": "Remove filter \"{optionName}\".", + "filterModal.item.hideOptions": "Hide \"{itemName}\" filter item options.", + "filterModal.item.showOptions": "Show \"{itemName}\" filter item options.", "filterSearch.name": "Enter a {name}", "footer.calloutText": "Lorem ipsum dolor sit amet, consectetur adipsicing elit, sed do eiusmod tempor incididunt ut labore et dolore.", "footer.followText": "Follow Us!", @@ -300,6 +310,7 @@ "productFullDetail.productDescription": "Product Description", "productFullDetail.unavailableProduct": "This product is currently unavailable for purchase.", "productList.each": " ea.", + "productList.filter": "Filter", "productList.outOfStock": "Out-of-stock", "productList.quantity": "Qty : {quantity}", "productListing.loading": "Fetching Cart...", diff --git a/packages/venia-ui/lib/RootComponents/Category/__tests__/__snapshots__/category.spec.js.snap b/packages/venia-ui/lib/RootComponents/Category/__tests__/__snapshots__/category.spec.js.snap index bbdc65c7b8..52fcecad21 100644 --- a/packages/venia-ui/lib/RootComponents/Category/__tests__/__snapshots__/category.spec.js.snap +++ b/packages/venia-ui/lib/RootComponents/Category/__tests__/__snapshots__/category.spec.js.snap @@ -15,6 +15,7 @@ Array [ }, } } + isLoading={false} pageControl={ Object { "currentPage": 1, @@ -77,116 +78,6 @@ exports[`Category Root Component error view renders when data is not present and `; -exports[`Category Root Component loading indicator does not render when data is present 1`] = ` -Array [ - "Meta", - , -] -`; - -exports[`Category Root Component loading indicator renders when data is not present 1`] = ` -
- - - - - - - - - - - - - - - -
-`; - exports[`Category Root Component renders the correct tree 1`] = ` Array [ "Meta", @@ -202,6 +93,7 @@ Array [ }, } } + isLoading={false} pageControl={ Object { "currentPage": 1, diff --git a/packages/venia-ui/lib/RootComponents/Category/__tests__/__snapshots__/categoryContent.spec.js.snap b/packages/venia-ui/lib/RootComponents/Category/__tests__/__snapshots__/categoryContent.spec.js.snap index dcd0dc4853..f19045737d 100644 --- a/packages/venia-ui/lib/RootComponents/Category/__tests__/__snapshots__/categoryContent.spec.js.snap +++ b/packages/venia-ui/lib/RootComponents/Category/__tests__/__snapshots__/categoryContent.spec.js.snap @@ -1,42 +1,445 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`filter button/modal does not render if there are no filters 1`] = ` +Array [ + , + "Title", +
+

+
+ Name +
+

+
+
+ +
+
+ +
+ +
+
+ +
+
, +] +`; + +exports[`filter button/modal renders when there are filters 1`] = ` +Array [ + , + "Title", +
+

+
+ Name +
+

+
+ +
+ +
+
+ +
+ +
+
+ +
+ +
, +] +`; + exports[`renders empty page 1`] = ` Array [ - , + , "Title",

-
+
Empty Name

-
- +
+ +
, +] +`; + +exports[`renders loading indicator if no data and loading 1`] = ` +Array [ + , + "Title", +
+

+
+ Name +
+

+
+
+ + + + + + + + + + + + + + + +
, ] `; exports[`renders the correct tree 1`] = ` Array [ - , + , + "Title", +
+

+
+ Name +
+

+
+
+ +
+
+ +
+ +
+
+ +
+
, +] +`; + +exports[`sort button/container does not render if there are no products 1`] = ` +Array [ + , "Title",

-
+
Name

-
+
+ +
, +] +`; + +exports[`sort button/container renders when there are products 1`] = ` +Array [ + , + "Title", +
+

+
+ Name +
+

+
+
+ +
+
+
{ expect(tree.toJSON()).toMatchSnapshot(); }); - describe('loading indicator', () => { - test('does not render when data is present', () => { - useCategory.mockReturnValueOnce({ - ...talonProps, - loading: true - }); - const tree = createTestInstance(); - expect(tree.toJSON()).toMatchSnapshot(); - }); - test('renders when data is not present', () => { - useCategory.mockReturnValueOnce({ - ...talonProps, - loading: true, - categoryData: undefined - }); - const tree = createTestInstance(); - expect(tree.toJSON()).toMatchSnapshot(); - }); - }); - describe('error view', () => { test('does not render when data is present', () => { useCategory.mockReturnValueOnce({ diff --git a/packages/venia-ui/lib/RootComponents/Category/__tests__/categoryContent.spec.js b/packages/venia-ui/lib/RootComponents/Category/__tests__/categoryContent.spec.js index 15d0fa30ea..76fac18f73 100644 --- a/packages/venia-ui/lib/RootComponents/Category/__tests__/categoryContent.spec.js +++ b/packages/venia-ui/lib/RootComponents/Category/__tests__/categoryContent.spec.js @@ -1,8 +1,9 @@ import React from 'react'; import { createTestInstance } from '@magento/peregrine'; - +import { useCategoryContent } from '@magento/peregrine/lib/talons/RootComponents/Category'; import CategoryContent from '../categoryContent'; +jest.mock('@magento/venia-ui/lib/classify'); jest.mock('@magento/peregrine/lib/context/app', () => { const state = {}; const api = { @@ -17,75 +18,122 @@ jest.mock('../../../components/Head', () => ({ StoreTitle: () => 'Title' })); +jest.mock('@magento/peregrine/lib/talons/RootComponents/Category', () => ({ + useCategoryContent: jest.fn() +})); + jest.mock('../../../components/Breadcrumbs', () => 'Breadcrumbs'); jest.mock('../../../components/Gallery', () => 'Gallery'); jest.mock('../../../components/Pagination', () => 'Pagination'); +jest.mock('../../../components/SortedByContainer', () => 'SortedByContainer'); +jest.mock( + '../../../components/FilterModalOpenButton', + () => 'FilterModalOpenButton' +); jest.mock('../NoProductsFound', () => 'NoProductsFound'); -const classes = { - root: 'a', - title: 'b', - gallery: 'c', - pagination: 'd' -}; - -const sortProps = [ - { sortDirection: '', sortAttribute: '', sortText: '' }, - jest.fn() -]; - -test('renders the correct tree', () => { - const data = { - category: { - name: 'Name', - description: 'test' - }, +const defaultProps = { + categoryId: 42, + data: { products: { items: { id: 1 - }, - page_info: { - total_pages: 1 } } - }; + }, + isLoading: false, + pageControl: {}, + sortProps: [ + { sortDirection: '', sortAttribute: '', sortText: '' }, + jest.fn() + ], + pageSize: 6 +}; - const instance = createTestInstance( - - ); +const talonProps = { + categoryName: 'Name', + categoryDescription: 'test', + filters: {}, + items: { + id: 1 + }, + totalPagesFromData: 1 +}; + +test('renders the correct tree', () => { + useCategoryContent.mockReturnValueOnce(talonProps); + const instance = createTestInstance(); expect(instance.toJSON()).toMatchSnapshot(); }); test('renders empty page', () => { - const data = { - category: { - name: 'Empty Name', - description: 'test' - }, + const props = { + ...defaultProps, products: { - items: null, - page_info: { - total_pages: 0 - } + items: null } }; + useCategoryContent.mockReturnValueOnce({ + ...talonProps, + categoryName: 'Empty Name', + totalPagesFromData: 0 + }); + const instance = createTestInstance(); + + expect(instance.toJSON()).toMatchSnapshot(); +}); - const instance = createTestInstance( - - ); +test('renders loading indicator if no data and loading', () => { + const props = { + ...defaultProps, + isLoading: true + }; + useCategoryContent.mockReturnValueOnce({ + ...talonProps, + totalPagesFromData: 0 + }); + const instance = createTestInstance(); expect(instance.toJSON()).toMatchSnapshot(); }); + +describe('filter button/modal', () => { + test('does not render if there are no filters', () => { + useCategoryContent.mockReturnValueOnce({ + ...talonProps, + filters: [] + }); + const tree = createTestInstance(); + expect(tree.toJSON()).toMatchSnapshot(); + }); + + test('renders when there are filters', () => { + useCategoryContent.mockReturnValueOnce({ + ...talonProps, + filters: [{}] + }); + const tree = createTestInstance(); + expect(tree.toJSON()).toMatchSnapshot(); + }); +}); + +describe('sort button/container', () => { + test('does not render if there are no products', () => { + useCategoryContent.mockReturnValueOnce({ + ...talonProps, + totalPagesFromData: 0 + }); + const tree = createTestInstance(); + expect(tree.toJSON()).toMatchSnapshot(); + }); + + test('renders when there are products', () => { + useCategoryContent.mockReturnValueOnce({ + ...talonProps, + totalPagesFromData: 1 + }); + const tree = createTestInstance(); + expect(tree.toJSON()).toMatchSnapshot(); + }); +}); diff --git a/packages/venia-ui/lib/RootComponents/Category/category.css b/packages/venia-ui/lib/RootComponents/Category/category.css index d589a6f023..ee8b2050dd 100644 --- a/packages/venia-ui/lib/RootComponents/Category/category.css +++ b/packages/venia-ui/lib/RootComponents/Category/category.css @@ -31,19 +31,3 @@ line-height: 1.375rem; text-align: center; } - -.sortContainer { - color: rgb(var(--venia-global-color-text-alt)); - text-align: center; - font-size: 0.875rem; - padding-bottom: 1rem; -} - -.sortText { - font-weight: 600; -} - -.filterButton { - composes: root_lowPriority from '../../components/Button/button.css'; - min-width: 6.25rem; -} diff --git a/packages/venia-ui/lib/RootComponents/Category/category.js b/packages/venia-ui/lib/RootComponents/Category/category.js index 4182ea27da..62d6c65dc9 100644 --- a/packages/venia-ui/lib/RootComponents/Category/category.js +++ b/packages/venia-ui/lib/RootComponents/Category/category.js @@ -2,7 +2,6 @@ import React, { Fragment } from 'react'; import { number, shape, string } from 'prop-types'; import { useCategory } from '@magento/peregrine/lib/talons/RootComponents/Category'; import { mergeClasses } from '../../classify'; -import { fullPageLoadingIndicator } from '../../components/LoadingIndicator'; import CategoryContent from './categoryContent'; import defaultClasses from './category.css'; @@ -33,11 +32,6 @@ const Category = props => { const classes = mergeClasses(defaultClasses, props.classes); if (!categoryData) { - // Show the loading indicator until data has been fetched. - if (loading) { - return fullPageLoadingIndicator; - } - if (error && pageControl.currentPage === 1) { if (process.env.NODE_ENV !== 'production') { console.error(error); @@ -54,6 +48,7 @@ const Category = props => { categoryId={id} classes={classes} data={categoryData} + isLoading={loading} pageControl={pageControl} sortProps={sortProps} pageSize={pageSize} diff --git a/packages/venia-ui/lib/RootComponents/Category/categoryContent.js b/packages/venia-ui/lib/RootComponents/Category/categoryContent.js index 4efca02f0f..ce2bac96d1 100644 --- a/packages/venia-ui/lib/RootComponents/Category/categoryContent.js +++ b/packages/venia-ui/lib/RootComponents/Category/categoryContent.js @@ -1,11 +1,9 @@ -import React, { Fragment, Suspense } from 'react'; +import React, { Fragment, Suspense, useMemo } from 'react'; import { array, number, shape, string } from 'prop-types'; -import { FormattedMessage } from 'react-intl'; import { useCategoryContent } from '@magento/peregrine/lib/talons/RootComponents/Category'; import { mergeClasses } from '../../classify'; import Breadcrumbs from '../../components/Breadcrumbs'; -import Button from '../../components/Button'; import Gallery from '../../components/Gallery'; import { StoreTitle } from '../../components/Head'; import Pagination from '../../components/Pagination'; @@ -13,11 +11,21 @@ import ProductSort from '../../components/ProductSort'; import RichContent from '../../components/RichContent'; import defaultClasses from './category.css'; import NoProductsFound from './NoProductsFound'; +import { fullPageLoadingIndicator } from '../../components/LoadingIndicator'; +import SortedByContainer from '../../components/SortedByContainer'; +import FilterModalOpenButton from '../../components/FilterModalOpenButton'; const FilterModal = React.lazy(() => import('../../components/FilterModal')); const CategoryContent = props => { - const { categoryId, data, pageControl, sortProps, pageSize } = props; + const { + categoryId, + data, + isLoading, + pageControl, + sortProps, + pageSize + } = props; const [currentSort] = sortProps; const talonProps = useCategoryContent({ @@ -30,72 +38,65 @@ const CategoryContent = props => { categoryName, categoryDescription, filters, - handleLoadFilters, - handleOpenFilters, items, totalPagesFromData } = talonProps; const classes = mergeClasses(defaultClasses, props.classes); - const maybeFilterButtons = filters ? ( - + const shouldShowFilterButtons = filters && filters.length; + + // If there are no products we can hide the sort button. + const shouldShowSortButtons = totalPagesFromData; + + const maybeFilterButtons = shouldShowFilterButtons ? ( + + ) : null; + + const filtersModal = shouldShowFilterButtons ? ( + ) : null; - const maybeSortButton = - totalPagesFromData && filters ? ( - - ) : null; - - const maybeSortContainer = - totalPagesFromData && filters ? ( -
- - - - -
- ) : null; - - // If you want to defer the loading of the FilterModal until user interaction - // (hover, focus, click), simply add the talon's `loadFilters` prop as - // part of the conditional here. - const modal = filters ? : null; + const maybeSortButton = shouldShowSortButtons ? ( + + ) : null; + + const maybeSortContainer = shouldShowSortButtons ? ( + + ) : null; const categoryDescriptionElement = categoryDescription ? ( ) : null; - const content = totalPagesFromData ? ( - -
- -
-
- -
-
- ) : ( - - ); + const content = useMemo(() => { + if (totalPagesFromData) { + return ( + +
+ +
+
+ +
+
+ ); + } else { + if (isLoading) { + return fullPageLoadingIndicator; + } else { + return ; + } + } + }, [ + categoryId, + classes.gallery, + classes.pagination, + isLoading, + items, + pageControl, + totalPagesFromData + ]); return ( @@ -103,7 +104,9 @@ const CategoryContent = props => { {categoryName}

-
{categoryName}
+
+ {categoryName || '...'} +

{categoryDescriptionElement}
@@ -112,7 +115,7 @@ const CategoryContent = props => {
{maybeSortContainer} {content} - {modal} + {filtersModal}
); diff --git a/packages/venia-ui/lib/components/Button/button.js b/packages/venia-ui/lib/components/Button/button.js index 1a373627d6..b3b666deaf 100644 --- a/packages/venia-ui/lib/components/Button/button.js +++ b/packages/venia-ui/lib/components/Button/button.js @@ -25,6 +25,7 @@ const Button = props => { type, negative, disabled, + ariaLabel, ...restProps } = props; const classes = mergeClasses(defaultClasses, propClasses); @@ -35,6 +36,7 @@ const Button = props => { className={rootClassName} type={type} disabled={disabled} + aria-label={ariaLabel} {...restProps} > {children} diff --git a/packages/venia-ui/lib/components/Checkbox/checkbox.js b/packages/venia-ui/lib/components/Checkbox/checkbox.js index 41f5e56806..11438bec88 100644 --- a/packages/venia-ui/lib/components/Checkbox/checkbox.js +++ b/packages/venia-ui/lib/components/Checkbox/checkbox.js @@ -33,13 +33,25 @@ export class Checkbox extends Component { }; render() { - const { classes, fieldState, id, label, message, ...rest } = this.props; + const { + classes, + fieldState, + id, + label, + message, + ariaLabel, + ...rest + } = this.props; const { value: checked } = fieldState; const icon = checked ? checkedIcon : uncheckedIcon; return ( -
`; exports[`Search Page Component filter button/modal does not render if there are no filters 1`] = ` @@ -128,21 +147,13 @@ exports[`Search Page Component filter button/modal renders when there are filter
- +
- - - - - - - - - - - - - - + 0 items + +
- -
+
+
+
+ + + + + + + + + + + + + + + +
+ `; exports[`Search Page Component search results does not render if data returned has empty array 1`] = ` @@ -381,21 +411,15 @@ exports[`Search Page Component search results heading renders a generic message } />
- - - - - - +
- - - - - - +
} />
- - - - - - +
- - - - - - +
'FilterModal'); jest.mock('../../ProductSort', () => 'ProductSort'); jest.mock('../../../components/Pagination', () => 'Pagination'); jest.mock('@magento/venia-ui/lib/classify'); +jest.mock('../../SortedByContainer', () => 'SortedByContainer'); +jest.mock('../../FilterModalOpenButton', () => 'FilterModalOpenButton'); const talonProps = { data: { diff --git a/packages/venia-ui/lib/components/SearchPage/searchPage.js b/packages/venia-ui/lib/components/SearchPage/searchPage.js index 1a746e802e..7ac40f2d94 100644 --- a/packages/venia-ui/lib/components/SearchPage/searchPage.js +++ b/packages/venia-ui/lib/components/SearchPage/searchPage.js @@ -1,4 +1,4 @@ -import React, { Fragment, Suspense } from 'react'; +import React, { Fragment, Suspense, useMemo } from 'react'; import { FormattedMessage, useIntl } from 'react-intl'; import { shape, string } from 'prop-types'; @@ -9,34 +9,32 @@ import Pagination from '../../components/Pagination'; import Gallery from '../Gallery'; import { fullPageLoadingIndicator } from '../LoadingIndicator'; import ProductSort from '../ProductSort'; -import Button from '../Button'; import defaultClasses from './searchPage.css'; +import SortedByContainer from '../SortedByContainer'; +import FilterModalOpenButton from '../FilterModalOpenButton'; const FilterModal = React.lazy(() => import('../FilterModal')); const SearchPage = props => { const classes = mergeClasses(defaultClasses, props.classes); - const talonProps = useSearchPage(); - const { data, error, filters, loading, - openDrawer, pageControl, searchCategory, searchTerm, sortProps } = talonProps; - const { formatMessage } = useIntl(); + const { formatMessage } = useIntl(); const [currentSort] = sortProps; + const content = useMemo(() => { + if (!data && loading) return fullPageLoadingIndicator; - if (!data) { - if (loading) return fullPageLoadingIndicator; - else if (error) { + if (!data && error) { return (
{
); } - } - - let content; - if (data.products.items.length === 0) { - content = ( -
- -
- ); - } else { - content = ( - -
- -
-
- -
-
- ); - } - - const totalCount = data.products.total_count || 0; - - const maybeFilterButtons = - filters && filters.length ? ( - - ) : null; - - const maybeFilterModal = - filters && filters.length ? : null; - - const maybeSortButton = totalCount ? ( + + if (!data) { + return null; + } + + if (data.products.items.length === 0) { + return ( +
+ +
+ ); + } else { + return ( + +
+ +
+
+ +
+
+ ); + } + }, [ + classes.gallery, + classes.noResult, + classes.pagination, + error, + loading, + data, + pageControl + ]); + + const productsCount = + data && data.products && data.products.total_count + ? data.products.total_count + : 0; + + const shouldShowFilterButtons = filters && filters.length; + + // If there are no products we can hide the sort button. + const shouldShowSortButtons = productsCount; + + const maybeFilterButtons = shouldShowFilterButtons ? ( + + ) : null; + + const maybeFilterModal = shouldShowFilterButtons ? ( + + ) : null; + + const maybeSortButton = shouldShowSortButtons ? ( ) : null; - const maybeSortContainer = totalCount ? ( - - - - - - + const maybeSortContainer = shouldShowSortButtons ? ( + ) : null; - const searchResultsHeading = searchTerm ? ( + const searchResultsHeading = !data ? null : searchTerm ? ( { id: 'searchPage.totalPages', defaultMessage: `items` }, - { totalCount } + { totalCount: productsCount } )}
diff --git a/packages/venia-ui/lib/components/SortedByContainer/index.js b/packages/venia-ui/lib/components/SortedByContainer/index.js new file mode 100644 index 0000000000..9ef98b00e1 --- /dev/null +++ b/packages/venia-ui/lib/components/SortedByContainer/index.js @@ -0,0 +1 @@ +export { default } from './sortedByContainer'; diff --git a/packages/venia-ui/lib/components/SortedByContainer/sortedByContainer.css b/packages/venia-ui/lib/components/SortedByContainer/sortedByContainer.css new file mode 100644 index 0000000000..4c718cbe69 --- /dev/null +++ b/packages/venia-ui/lib/components/SortedByContainer/sortedByContainer.css @@ -0,0 +1,10 @@ +.root { + color: rgb(var(--venia-global-color-text-alt)); + text-align: center; + font-size: 0.875rem; + padding-bottom: 1rem; +} + +.sortText { + font-weight: 600; +} diff --git a/packages/venia-ui/lib/components/SortedByContainer/sortedByContainer.js b/packages/venia-ui/lib/components/SortedByContainer/sortedByContainer.js new file mode 100644 index 0000000000..b717c024af --- /dev/null +++ b/packages/venia-ui/lib/components/SortedByContainer/sortedByContainer.js @@ -0,0 +1,36 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { FormattedMessage } from 'react-intl'; +import { mergeClasses } from '../../classify'; +import defaultClasses from './sortedByContainer.css'; + +const SortedByContainer = props => { + const { currentSort } = props; + + const classes = mergeClasses(defaultClasses, props.classes); + + return ( +
+ + + + +
+ ); +}; + +export default SortedByContainer; + +SortedByContainer.propTypes = { + shouldDisplay: PropTypes.bool, + currentSort: PropTypes.shape({ + sortId: PropTypes.string, + sortText: PropTypes.string + }) +}; diff --git a/packages/venia-ui/lib/components/Trigger/trigger.js b/packages/venia-ui/lib/components/Trigger/trigger.js index 8522883225..534ee26a8f 100644 --- a/packages/venia-ui/lib/components/Trigger/trigger.js +++ b/packages/venia-ui/lib/components/Trigger/trigger.js @@ -15,12 +15,17 @@ import defaultClasses from './trigger.css'; * @returns {React.Element} A React component that when triggered invokes the action. */ const Trigger = props => { - const { action, children } = props; + const { action, children, ariaLabel } = props; const classes = mergeClasses(defaultClasses, props.classes); return ( - ); diff --git a/packages/venia-ui/package.json b/packages/venia-ui/package.json index 751707ad1d..17e103a6ed 100644 --- a/packages/venia-ui/package.json +++ b/packages/venia-ui/package.json @@ -41,6 +41,7 @@ "lodash.throttle": "~4.1.1", "memoize-one": "~5.0.0", "prop-types": "~15.7.2", + "react-aria": "~3.4.0", "react-feather": "~2.0.3", "react-helmet-async": "^1.0.2", "react-slick": "~0.25.2", diff --git a/yarn.lock b/yarn.lock index 2f5873e249..f775a99c31 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1782,6 +1782,13 @@ dependencies: regenerator-runtime "^0.13.4" +"@babel/runtime@^7.6.2": + version "7.13.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.13.2.tgz#9511c87d2808b2cf5fb9e9c5cf0d1ab789d75499" + integrity sha512-U9plpxyudmZNYe12YI6cXyeWTWYCTq2u1h+C0XVtC3+BoiuzTh1BHlMJgxMrbKTombYkf7wQGqoxYkptFehuZw== + dependencies: + regenerator-runtime "^0.13.4" + "@babel/runtime@^7.8.4": version "7.9.6" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.9.6.tgz#a9102eb5cadedf3f31d08a9ecf294af7827ea29f" @@ -2186,6 +2193,21 @@ resolved "https://registry.yarnpkg.com/@icons/material/-/material-0.2.4.tgz#e90c9f71768b3736e76d7dd6783fc6c2afa88bc8" integrity sha512-QPcGmICAPbGLGb6F/yNf/KzKqvFx8z5qx3D1yFqVAjoFmXK35EgyW+cJ57Te3CNsmzblwtzakLGFqHPqrfb4Tw== +"@internationalized/message@3.0.0-alpha.0": + version "3.0.0-alpha.0" + resolved "https://registry.yarnpkg.com/@internationalized/message/-/message-3.0.0-alpha.0.tgz#83015e2057d2b6b5034a3e23983b1e051f9d9e36" + integrity sha512-NT2eiVq5f5z7Yi9Hmchb8GAGYjEpYbYcD4u/Oxo5XG9XFbrnz7zNvrJJlzuQ+2jPozabq6pFKurqaFmM49DYUg== + dependencies: + "@babel/runtime" "^7.6.2" + intl-messageformat "^2.2.0" + +"@internationalized/number@3.0.0-alpha.0": + version "3.0.0-alpha.0" + resolved "https://registry.yarnpkg.com/@internationalized/number/-/number-3.0.0-alpha.0.tgz#27190fbc1d73a24ac96dfafdfe7aa4e520090eed" + integrity sha512-8aOD2I3HmEscIZO/cm1jkcrYMSmRPhoW9G1OsuQb4Ge/Y9HsJVGB9otTylUEXJUmoXi/eD8Mr1gx3+0FLCM4eA== + dependencies: + "@babel/runtime" "^7.6.2" + "@istanbuljs/load-nyc-config@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.0.0.tgz#10602de5570baea82f8afbfa2630b24e7a8cfe5b" @@ -2551,6 +2573,620 @@ prop-types "^15.6.1" react-lifecycles-compat "^3.0.4" +"@react-aria/breadcrumbs@^3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@react-aria/breadcrumbs/-/breadcrumbs-3.1.2.tgz#5d215d84a2e294db60d3ca62361d9ccdf332dbf4" + integrity sha512-rrRxHthNF4SRqufOi2nf9ii84weT+SOhEk3cOpgmcLUhQg9G9uFUc53W7LBOrLxG8HvgwMZoktq7ru3fmUFkXg== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/i18n" "^3.1.2" + "@react-aria/interactions" "^3.2.1" + "@react-aria/link" "^3.1.2" + "@react-aria/utils" "^3.5.0" + "@react-types/breadcrumbs" "^3.2.0" + "@react-types/shared" "^3.2.1" + +"@react-aria/button@^3.3.1": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@react-aria/button/-/button-3.3.1.tgz#f180ffa95e3e822b7da4937421cf8280dd17af17" + integrity sha512-LXNuo0L79AhYqnxV+Y3J3xt7hPcmCVCEpZaC/dBzovR1MLunrdpk3QAXsRt3tqza1XvoqdvNhNHQm1Z1kyBTUg== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/focus" "^3.2.2" + "@react-aria/i18n" "^3.3.0" + "@react-aria/interactions" "^3.3.3" + "@react-aria/utils" "^3.6.0" + "@react-stately/toggle" "^3.2.1" + "@react-types/button" "^3.3.1" + +"@react-aria/checkbox@^3.2.1": + version "3.2.1" + resolved "https://registry.yarnpkg.com/@react-aria/checkbox/-/checkbox-3.2.1.tgz#493d9d584b4db474645a4565c4f899ee3a579f07" + integrity sha512-XnypnlVIfhB3CD7eSjSds8hNkzHgnhu0t48I1D0jYdL1O6tQC4UytPdIqlemRYBVHDloZkWerbjenpHnxhv8iA== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/label" "^3.1.1" + "@react-aria/toggle" "^3.1.1" + "@react-aria/utils" "^3.3.0" + "@react-stately/checkbox" "^3.0.1" + "@react-stately/toggle" "^3.2.1" + "@react-types/checkbox" "^3.2.1" + +"@react-aria/dialog@^3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@react-aria/dialog/-/dialog-3.1.2.tgz#868970e7fdaa6ddb91a0d8d5b492778607d417fd" + integrity sha512-CUHzLdcKxnQ1IpbJOJ3BIDe762QoTOFXZfDAheNiTi24ym85w7KkW7dnfJDK2+J5RY15c5KWooOZvTaBmIJ7Xw== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/focus" "^3.2.2" + "@react-aria/utils" "^3.3.0" + "@react-stately/overlays" "^3.1.1" + "@react-types/dialog" "^3.3.0" + +"@react-aria/focus@^3.2.2", "@react-aria/focus@^3.2.3": + version "3.2.3" + resolved "https://registry.yarnpkg.com/@react-aria/focus/-/focus-3.2.3.tgz#3e4137498a7fb5235d056c30fd94ab4a82e73aea" + integrity sha512-+OWmJMivrq3f8ApWihH1KJYqYj3rZV34YJORacBohcAsF1Qd1V1/P+w3dMkf24kV0wqAiWePCF1FwgnrL/rYzQ== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/interactions" "^3.3.0" + "@react-aria/utils" "^3.4.0" + "@react-types/shared" "^3.3.0" + clsx "^1.1.1" + +"@react-aria/i18n@^3.1.2", "@react-aria/i18n@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@react-aria/i18n/-/i18n-3.3.0.tgz#7f92ae81f6536b19b17b89c0991ddb6c10f2512a" + integrity sha512-8KYk0tQiEf9Kd9xdF4cKliP1169WSIryKFnZgnm9dvZl96TyfDK1xJpZQy58XjRdbS/H45CKydFmMcZEElu3BQ== + dependencies: + "@babel/runtime" "^7.6.2" + "@internationalized/message" "3.0.0-alpha.0" + "@internationalized/number" "3.0.0-alpha.0" + "@react-aria/ssr" "^3.0.1" + "@react-aria/utils" "^3.6.0" + "@react-types/shared" "^3.4.0" + +"@react-aria/interactions@^3.2.1", "@react-aria/interactions@^3.3.0", "@react-aria/interactions@^3.3.3": + version "3.3.3" + resolved "https://registry.yarnpkg.com/@react-aria/interactions/-/interactions-3.3.3.tgz#02852a11530f73d1ae4525cdef7c2595acde2fdc" + integrity sha512-wq6YwVFMzT7jdpVGqGoqXPCANHl6BvOOL1Lrg3vb+df5pvoCFNWBytqv/yQVpT4PKOSUbxSBdOTubvtZlu0l+g== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/utils" "^3.6.0" + "@react-types/shared" "^3.4.0" + +"@react-aria/label@^3.1.1": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@react-aria/label/-/label-3.1.1.tgz#03dc5c4813cd1f51760ba48783c186c2eeda1189" + integrity sha512-9kZKJonYSXeY6hZULZrsujAb6uXDGEy8qPq0tjTVoTA3+gx26LOmLCLgvHFtxUK1e4s99rHmaSPdOtq5qu3EVQ== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/utils" "^3.3.0" + "@react-types/label" "^3.2.1" + "@react-types/shared" "^3.2.1" + +"@react-aria/link@^3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@react-aria/link/-/link-3.1.2.tgz#0a39e44fb1a7bb30e2ef0c88e0f248462998c87a" + integrity sha512-ONAyB+2irMSNnv2qZKw51AwYv1GzFXAn+N4nWxreI+TIzhAA6JBkMYT9I6JFqx51UwvGI+ys0YXAMJVIBeZRvA== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/interactions" "^3.2.1" + "@react-aria/utils" "^3.3.0" + "@react-types/link" "^3.1.1" + "@react-types/shared" "^3.2.1" + +"@react-aria/listbox@^3.2.4": + version "3.2.4" + resolved "https://registry.yarnpkg.com/@react-aria/listbox/-/listbox-3.2.4.tgz#3162e47d64e1f6cd8fdfe45766cb88c3852a525d" + integrity sha512-IYs4oS2wzWVcWEtKG57zZLZI507WlDy24wuzymwgFxxIRXDVaBsSMOs7+uE7N1P4fLOa1yAlv170AvKDDbIJ2g== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/interactions" "^3.3.3" + "@react-aria/label" "^3.1.1" + "@react-aria/selection" "^3.3.2" + "@react-aria/utils" "^3.6.0" + "@react-stately/collections" "^3.3.0" + "@react-stately/list" "^3.2.2" + "@react-types/listbox" "^3.1.1" + "@react-types/shared" "^3.4.0" + +"@react-aria/menu@^3.1.4": + version "3.1.4" + resolved "https://registry.yarnpkg.com/@react-aria/menu/-/menu-3.1.4.tgz#5ad8c360505ab079c05c30a401331b55b1038794" + integrity sha512-e1DXZqvqIgPWmYkj7DTGmsPPZJzMRHkOp9+qLS6lVjgSvdzKZPi96MJPanMYB7NB/oEsaFiOE7W3q4EhuA0j8g== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/interactions" "^3.3.3" + "@react-aria/overlays" "^3.6.1" + "@react-aria/selection" "^3.3.2" + "@react-aria/utils" "^3.6.0" + "@react-stately/collections" "^3.3.0" + "@react-stately/menu" "^3.2.1" + "@react-stately/tree" "^3.1.2" + "@react-types/button" "^3.3.1" + "@react-types/menu" "^3.1.1" + "@react-types/shared" "^3.4.0" + +"@react-aria/meter@^3.1.1": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@react-aria/meter/-/meter-3.1.1.tgz#2b3bff2cc2b8c3f552a5edbea444ce9d9f073079" + integrity sha512-Soh+jDEA7onv/wbbdhxUvNqnNp1WgHY3eMDjOXkGpTVozc8wUwMxBCwdPTIXnxMyvFXbzqYNGZOxF/9gsO32yg== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/progress" "^3.1.1" + "@react-types/meter" "^3.1.1" + "@react-types/shared" "^3.2.1" + +"@react-aria/overlays@^3.6.1": + version "3.6.1" + resolved "https://registry.yarnpkg.com/@react-aria/overlays/-/overlays-3.6.1.tgz#0354088b27f925d64c6900f236198b6a869f83d3" + integrity sha512-rZrx39yZBzc9WbgX6fADmcht0pCFdTQl+9+sZwWb419SFPAGRzMUU1h9kai/5u0Yp4osPrJeu0hEz/rM4fBJOw== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/i18n" "^3.3.0" + "@react-aria/interactions" "^3.3.3" + "@react-aria/utils" "^3.6.0" + "@react-aria/visually-hidden" "^3.2.1" + "@react-stately/overlays" "^3.1.1" + "@react-types/button" "^3.3.1" + "@react-types/overlays" "^3.4.0" + dom-helpers "^3.3.1" + +"@react-aria/progress@^3.1.1": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@react-aria/progress/-/progress-3.1.1.tgz#053b7c15a67ca4a4c9feb50f4a4f2f5c2345521f" + integrity sha512-Y17ziWi5EoveF8QFQ+JyOvCjUCIYVNQUbr+TpuBossTQd3XEK/Dje0I/ZJ65q+tuBEtfnW2qoWpZzYCrQnGu9Q== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/i18n" "^3.1.2" + "@react-aria/label" "^3.1.1" + "@react-aria/utils" "^3.3.0" + "@react-types/progress" "^3.1.1" + "@react-types/shared" "^3.2.1" + +"@react-aria/radio@^3.1.3": + version "3.1.3" + resolved "https://registry.yarnpkg.com/@react-aria/radio/-/radio-3.1.3.tgz#65b156fc61a9e747dcacfbc8cf6043a3fc38a923" + integrity sha512-Q4Z1Fld9InZPnAAKqH3HcLiH0MO6rCMBOXJif6bs1HUlagc3vzT3e235dWCxzmn3XCqAOooX/sLD8O3sA8ZvfA== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/focus" "^3.2.2" + "@react-aria/i18n" "^3.3.0" + "@react-aria/interactions" "^3.3.3" + "@react-aria/label" "^3.1.1" + "@react-aria/utils" "^3.6.0" + "@react-stately/radio" "^3.3.0" + "@react-types/radio" "^3.1.1" + +"@react-aria/searchfield@^3.1.1": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@react-aria/searchfield/-/searchfield-3.1.1.tgz#5fdd74d0b39633aebf2f66050a74d6cc03fd953f" + integrity sha512-wM6EMCAytuG3XwLYBkesj+l8k17esFT7hmYqOrj56LZ7fYkP5vIA5kpgLudPpovbUCVAMN8IEp84qDVtl9khGA== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/i18n" "^3.1.2" + "@react-aria/interactions" "^3.2.1" + "@react-aria/textfield" "^3.2.1" + "@react-aria/utils" "^3.3.0" + "@react-stately/searchfield" "^3.1.1" + "@react-types/button" "^3.2.1" + "@react-types/searchfield" "^3.1.1" + "@react-types/shared" "^3.2.1" + +"@react-aria/select@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@react-aria/select/-/select-3.3.0.tgz#81884563e59fa4a86e74f87a52c5abc60ec83956" + integrity sha512-7zbQncmafiMAZCslSe2hAeyCKxgqWuf83zOd23NPrEumA/i3h8cnCs1CoCA+xCFvsXCWtHgRhEFXqZlAlNOiLQ== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/i18n" "^3.3.0" + "@react-aria/interactions" "^3.3.3" + "@react-aria/label" "^3.1.1" + "@react-aria/menu" "^3.1.4" + "@react-aria/selection" "^3.3.2" + "@react-aria/utils" "^3.6.0" + "@react-aria/visually-hidden" "^3.2.1" + "@react-stately/select" "^3.1.1" + "@react-types/button" "^3.3.1" + "@react-types/select" "^3.2.0" + "@react-types/shared" "^3.4.0" + +"@react-aria/selection@^3.3.2": + version "3.3.2" + resolved "https://registry.yarnpkg.com/@react-aria/selection/-/selection-3.3.2.tgz#35e46335d8882b1ee887d5f3c245117a29794d4e" + integrity sha512-HhMJR8UN7MQg0XqNbFIhuH0YDf7tEAp+xa5KfyyXjAG7sjTkoYwB212NfxtevNChnXWb19gdoF0IEVHVKuoxkA== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/focus" "^3.2.3" + "@react-aria/i18n" "^3.3.0" + "@react-aria/interactions" "^3.3.3" + "@react-aria/utils" "^3.6.0" + "@react-stately/collections" "^3.3.0" + "@react-stately/selection" "^3.3.0" + "@react-types/shared" "^3.4.0" + +"@react-aria/separator@^3.1.1": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@react-aria/separator/-/separator-3.1.1.tgz#bfcd71bb5ab50dc04a7f307b84bd77955f08002f" + integrity sha512-VbiqQsTtKKMjvMcPVWgTbDHzx7qMP3VFC+y9cEVajicMwRoO4bn7kJgcSzainXpWx70bhT5RW1mt84fzxMF+Lg== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/utils" "^3.3.0" + "@react-types/shared" "^3.2.1" + +"@react-aria/slider@^3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@react-aria/slider/-/slider-3.0.1.tgz#c1d99d7303fe269bd57a9504ba13c6b34c830fd3" + integrity sha512-qRmdn+6BrcgDkUqlPmkqr11GOxpOdeNjTAMYPCD5cXxbZdio1INGDtIQkQG8G7RIBld1Auhq7leeFfT4f7vhdg== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/focus" "^3.2.3" + "@react-aria/i18n" "^3.3.0" + "@react-aria/interactions" "^3.3.3" + "@react-aria/label" "^3.1.1" + "@react-aria/utils" "^3.6.0" + "@react-stately/radio" "^3.3.0" + "@react-stately/slider" "^3.0.1" + "@react-types/radio" "^3.1.1" + "@react-types/slider" "^3.0.1" + +"@react-aria/ssr@^3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@react-aria/ssr/-/ssr-3.0.1.tgz#5f7c111f9ecd184b8f6140139703c1ee552dca30" + integrity sha512-rweMNcSkUO4YkcmgFIoZFvgPyHN2P9DOjq3VOHnZ8SG3Y4TTvSY6Iv90KgzeEfmWCUqqt65FYH4JgrpGNToEMw== + dependencies: + "@babel/runtime" "^7.6.2" + +"@react-aria/switch@^3.1.1": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@react-aria/switch/-/switch-3.1.1.tgz#a67239302908426dedc383a05bf7543190bec948" + integrity sha512-VPuonUcZ0IFs3FAAL3cAWtZr95DH0nyzTWDgVfbfGQCz6zVcD1R6OlA0mUPEdqUl5jQamBvFIk/W/5KbtrpdQw== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/toggle" "^3.1.1" + "@react-stately/toggle" "^3.2.1" + "@react-types/switch" "^3.1.1" + +"@react-aria/textfield@^3.2.1", "@react-aria/textfield@^3.2.2": + version "3.2.2" + resolved "https://registry.yarnpkg.com/@react-aria/textfield/-/textfield-3.2.2.tgz#2e8195668464911d4f7a363d19da8786c10afd22" + integrity sha512-oIIvy82uBTZqNyHivObFbVtUFMU7GsssIq8T195c0hiuUISoaUxhrV1zlqeo3Ny/WOf275+kGF3UNnkWXihmBg== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/focus" "^3.2.2" + "@react-aria/label" "^3.1.1" + "@react-aria/utils" "^3.4.1" + "@react-types/shared" "^3.2.1" + "@react-types/textfield" "^3.2.2" + +"@react-aria/toggle@^3.1.1": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@react-aria/toggle/-/toggle-3.1.2.tgz#b21c55c103cbeb47baed1e76406aca778e77e8dd" + integrity sha512-oFGo1ABma44hTZvBJWAgpxDr1FkRegk/UL9rAYvrKTBQIRXarvHm0Yv4BmHq/ZWYhHhNWsg07A6CntBQBZFG/A== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/focus" "^3.2.2" + "@react-aria/interactions" "^3.3.3" + "@react-aria/utils" "^3.6.0" + "@react-stately/toggle" "^3.2.1" + "@react-types/checkbox" "^3.2.2" + "@react-types/shared" "^3.4.0" + "@react-types/switch" "^3.1.1" + +"@react-aria/tooltip@^3.1.1": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@react-aria/tooltip/-/tooltip-3.1.1.tgz#e0dfdd9e51b581563f684927249d70e1bad761e3" + integrity sha512-wTszWN6lG3A9Ofdrhv1vG9aOmoqzuUZCbG9ZbXZ9+RtiOMwP/WnuSLWXcMH+KaWYpaImy7h1MDfOgHeaPxCbag== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/focus" "^3.2.3" + "@react-aria/interactions" "^3.3.3" + "@react-aria/overlays" "^3.6.1" + "@react-aria/utils" "^3.6.0" + "@react-stately/tooltip" "^3.0.2" + "@react-types/shared" "^3.4.0" + "@react-types/tooltip" "^3.1.1" + +"@react-aria/utils@^3.3.0", "@react-aria/utils@^3.4.0", "@react-aria/utils@^3.4.1", "@react-aria/utils@^3.5.0", "@react-aria/utils@^3.6.0": + version "3.6.0" + resolved "https://registry.yarnpkg.com/@react-aria/utils/-/utils-3.6.0.tgz#b7446f202469015713af8bf2812b748e694eca12" + integrity sha512-DO5F00T5NQ7j3GGWvruV8HrEd3YcN7KfbbvKvNZ3JWHETHNJxIc2xBz4Af6FSQzAjHkOrapd++SNoNLutRSz9Q== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/ssr" "^3.0.1" + "@react-stately/utils" "^3.2.0" + "@react-types/shared" "^3.4.0" + clsx "^1.1.1" + +"@react-aria/visually-hidden@^3.2.1": + version "3.2.1" + resolved "https://registry.yarnpkg.com/@react-aria/visually-hidden/-/visually-hidden-3.2.1.tgz#c022c562346140a473242448045add59269a74fd" + integrity sha512-ba7bQD09MuzUghtPyrQoXHgQnRRfOu039roVKPz2em9gHD0Wy4ap2UPwlzx35KzNq6FdCzMDZeSZHSnUWlzKnw== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/interactions" "^3.2.1" + "@react-aria/utils" "^3.3.0" + clsx "^1.1.1" + +"@react-stately/checkbox@^3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@react-stately/checkbox/-/checkbox-3.0.1.tgz#2e48a2085f1559549df62c1eda78299127acaf80" + integrity sha512-5rUx31X2NX78+vu/Ig4F9u0GnCeLAKD9N+BeGZXzJ/pTBIxoS/iAd9hegic4HKeulSrdYgNEpy3MMUPxhM9BkQ== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-stately/toggle" "^3.2.1" + "@react-stately/utils" "^3.1.1" + "@react-types/checkbox" "^3.2.1" + +"@react-stately/collections@^3.2.1", "@react-stately/collections@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@react-stately/collections/-/collections-3.3.0.tgz#d1e66077b47a8b6a9abcac66f1052d4b8851ce47" + integrity sha512-Y8Pfugw/tYbcR9F6GTiTkd9O4FiXErxi5aDLSZ/knS6v0pvr3EHsC3T7jLW+48dSNrwl+HkMe5ECMhWSUA1jRQ== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-types/shared" "^3.2.1" + +"@react-stately/list@^3.2.1", "@react-stately/list@^3.2.2": + version "3.2.2" + resolved "https://registry.yarnpkg.com/@react-stately/list/-/list-3.2.2.tgz#fb368cc7678503179202d11aef0ef8d48d1cbf12" + integrity sha512-8sJvy0cUhllhUMadYjX1qKmTxAWMRGxkvZpU/6reOEChlvibjAwbn2paoR8yZ+ppieeQOBe+AAYTl53gK8fKDA== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-stately/collections" "^3.3.0" + "@react-stately/selection" "^3.2.1" + "@react-stately/utils" "^3.1.1" + "@react-types/shared" "^3.2.1" + +"@react-stately/menu@^3.2.1": + version "3.2.1" + resolved "https://registry.yarnpkg.com/@react-stately/menu/-/menu-3.2.1.tgz#314646217e5dd49fa1da6886d33f485d44d6f0dd" + integrity sha512-8cpCynynjjn3qWNzrZMJEpsdk4tkXK9q3Xaw0ADqVym/NC/wPU3P3cqL4HY+ETar01tS2x8K23qYHbOZz0cQtQ== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-stately/overlays" "^3.1.1" + "@react-stately/utils" "^3.1.1" + "@react-types/menu" "^3.1.1" + "@react-types/shared" "^3.2.1" + +"@react-stately/overlays@^3.1.1": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@react-stately/overlays/-/overlays-3.1.1.tgz#6c1a393b77148184f7b1df22ece832d694d5a8b4" + integrity sha512-79YYXvmWKflezNPhc4fvXA1rDZurZvvEJcmbStNlR5Ryrnk/sQiOQCoVWooi2M4glSMT3UOTvD7YEnXxARcuIQ== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-stately/utils" "^3.1.1" + "@react-types/overlays" "^3.2.1" + +"@react-stately/radio@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@react-stately/radio/-/radio-3.3.0.tgz#6c8c980370f267011bbc0a79c080b4bf35274c1b" + integrity sha512-CcQT/UtiPx7Cy3+9gGcY/J3YH61/U3pw8jwoHA7lBBbqKH7b5Wjbis/UP9wv4tDBeUYPV0MdXlJjGBjyKt5Kow== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-stately/utils" "^3.2.0" + "@react-types/radio" "^3.1.1" + +"@react-stately/searchfield@^3.1.1": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@react-stately/searchfield/-/searchfield-3.1.1.tgz#fcada7bff9cac5bc4ffed11ba9cd06b8513be72a" + integrity sha512-asSTsM+H7kZB8XCIAQO0nqMm5onS+2d1yT351NEj42eAsliz5Zf/eZAsEo4Up8W77scDPxhFpaUigYMqjoFPyQ== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-stately/utils" "^3.1.1" + "@react-types/searchfield" "^3.1.1" + "@react-types/shared" "^3.2.1" + +"@react-stately/select@^3.1.1": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@react-stately/select/-/select-3.1.1.tgz#f49602ee7fc71f14550360bfa7c5becab58ac877" + integrity sha512-cl63nW66IJPsn9WQjKvghAIFKdFKuU1txx4zdEGY9tcwB/Yc+bgniLGOOTExJqN/RdPW9uBny5jjWcc4OQXyJA== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-stately/collections" "^3.2.1" + "@react-stately/list" "^3.2.1" + "@react-stately/menu" "^3.2.1" + "@react-stately/selection" "^3.2.1" + "@react-stately/utils" "^3.1.1" + "@react-types/select" "^3.1.1" + "@react-types/shared" "^3.2.1" + +"@react-stately/selection@^3.2.1", "@react-stately/selection@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@react-stately/selection/-/selection-3.3.0.tgz#2feebf1be600a3ae8cca32c2fcedc2c5703e8541" + integrity sha512-nVE3GOl9763t63Z+Cd5xwtGeXtSQVmYNfFfW6U0kdTm/y6SbBHYMauatAOzzMzayGmGeTmh4p8AQA8Du+Hm9Ug== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-stately/collections" "^3.2.1" + "@react-stately/utils" "^3.1.1" + "@react-types/shared" "^3.3.0" + +"@react-stately/slider@^3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@react-stately/slider/-/slider-3.0.1.tgz#076c149947ae45f5eda30178b368ad0c4052f2a3" + integrity sha512-gGpfdVbTmdsOvrmZvFx4hJ5b7nczvAWdHR/tFFJKfxH0/V8NudZ5hGnawY84R3x+OvgV+tKUfifEUKA+oJyG5w== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-aria/i18n" "^3.3.0" + "@react-aria/utils" "^3.6.0" + "@react-stately/utils" "^3.2.0" + "@react-types/slider" "^3.0.1" + +"@react-stately/toggle@^3.2.1": + version "3.2.1" + resolved "https://registry.yarnpkg.com/@react-stately/toggle/-/toggle-3.2.1.tgz#8b10b5eb99c3c4df2c36d17a5f23b77773ed7722" + integrity sha512-gZVuJ8OYoATUoXzdprsyx6O1w3wCrN+J0KnjhrjjKTrBG68n3pZH0p6dM0XpsaCzlSv0UgNa4fhHS3dYfr/ovw== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-stately/utils" "^3.1.1" + "@react-types/checkbox" "^3.2.1" + "@react-types/shared" "^3.2.1" + +"@react-stately/tooltip@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@react-stately/tooltip/-/tooltip-3.0.2.tgz#8440728c5ad51598368f3641c46cecbd1c523241" + integrity sha512-edFj2nDwu2eT9/nhnZwX/QAlf1bMtVheEGNhKKO99usXjLXE/e4v82diPtsPJBYoAyB3bLra4gjad5HBy33wSQ== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-stately/overlays" "^3.1.1" + "@react-stately/utils" "^3.2.0" + "@react-types/tooltip" "^3.1.1" + +"@react-stately/tree@^3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@react-stately/tree/-/tree-3.1.2.tgz#54e49cc7fa283ce21d67f642522c8f281c58b309" + integrity sha512-i3HOx/UQXA48qR5p/44JdX2lPb+3f3c2h/4YX+1fDtxjn0r/JkaEnPfo6zYTf40b7dU9mMOLWNF2qbGo59uIyQ== + dependencies: + "@babel/runtime" "^7.6.2" + "@react-stately/collections" "^3.2.1" + "@react-stately/selection" "^3.2.1" + "@react-stately/utils" "^3.1.1" + "@react-types/shared" "^3.2.1" + +"@react-stately/utils@^3.1.1", "@react-stately/utils@^3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@react-stately/utils/-/utils-3.2.0.tgz#0b90a70fee3236025ad8bed1f0e3555d5fc10296" + integrity sha512-vVBJvHVLnQySgqZ7OfP3ngDdwfGscJDsSD3WcN5ntHiT3JlZ5bksQReDkJEs20SFu2ST4w/0K7O4m97SbuMl2Q== + dependencies: + "@babel/runtime" "^7.6.2" + +"@react-types/breadcrumbs@^3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@react-types/breadcrumbs/-/breadcrumbs-3.2.0.tgz#c30d236f4073bebb89d7e2603e1d077e4e26b818" + integrity sha512-LmYOZwEbVl3QnjCmc6H3qVTukAQ2mAzwP2jxzmAnzk3dD+jPhsij/G8PWgTZI3oXCM/vSmLxqG8ga7FtrAx2SQ== + dependencies: + "@react-types/shared" "^3.2.1" + +"@react-types/button@^3.2.1", "@react-types/button@^3.3.1": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@react-types/button/-/button-3.3.1.tgz#4bdd325bc7df19c33911af256f63eae91e2a452e" + integrity sha512-xKLGSzGfsDBMe0SM7icOLNmzW38sdNSDSGMdrTLd3ygxb6pXY/LlcTdx7Sq28hdW8XL/ikFAnoQeS1VLXZHj7w== + dependencies: + "@react-types/shared" "^3.4.0" + +"@react-types/checkbox@^3.2.1", "@react-types/checkbox@^3.2.2": + version "3.2.2" + resolved "https://registry.yarnpkg.com/@react-types/checkbox/-/checkbox-3.2.2.tgz#7182d44a533e2ffd2c9118372cbc2c33b006eb18" + integrity sha512-WAAqLdjf6GUWjsMN5NaFMFumOtGTq+3+48CpM0ah2L+qmhMdj1s4gvHDerhls6u4ovRK/7zhg7XK+qQwcYVqMg== + dependencies: + "@react-types/shared" "^3.4.0" + +"@react-types/dialog@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@react-types/dialog/-/dialog-3.3.0.tgz#60a2b53f250ee082b53aef9340c80f1afe654bc7" + integrity sha512-63Vsr/UOZiaajlNDQUgWDi6v3EMenV1f8Cwh+L4lcyIJnbC6WeC2VEV3ld/TYVC0U58SQ0k7u2EIyHkWjc5kdQ== + dependencies: + "@react-types/overlays" "^3.2.1" + "@react-types/shared" "^3.2.1" + +"@react-types/label@^3.2.1": + version "3.4.0" + resolved "https://registry.yarnpkg.com/@react-types/label/-/label-3.4.0.tgz#6023dc9dd0146324ead52e08540cd60e57a3e27f" + integrity sha512-l84ysm1dcjL/5qVk9iN74z+/Ul0999XqnwTu6aTbuwAXqMk2sTU45eK2Yp/FJ7YWeflcF1vsomTkjMkX0BHKMw== + dependencies: + "@react-types/shared" "^3.4.0" + +"@react-types/link@^3.1.1": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@react-types/link/-/link-3.1.1.tgz#6cbaa0b1e5cf1492dd59a8f8f645308848395306" + integrity sha512-sTyr6fEjwBWXGp/7iU/+ncO0O8YHnf53ZdB7+vOZX+7w1smQ2yVAllRHrREcnEXijMBfuoWf2i0pNqgQBdmLwQ== + dependencies: + "@react-aria/interactions" "^3.2.1" + "@react-types/shared" "^3.2.1" + +"@react-types/listbox@^3.1.1": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@react-types/listbox/-/listbox-3.1.1.tgz#b896303ccb87123cf59ee2c089953d7928497c9b" + integrity sha512-HAljfdpbyLoJL9iwqz7Fw9MOmRwfzODeN+sr5ncE0eXJxnRBFhb5LjbjAN1dUBrKFBkv3etGlYu5HvX+PJjpew== + dependencies: + "@react-types/shared" "^3.2.1" + +"@react-types/menu@^3.1.1": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@react-types/menu/-/menu-3.1.1.tgz#e5aa52ac07c083243540dd5da0790a85fd1628c6" + integrity sha512-/xZWp4/3P/8dKFAGuzxz8IccSXvJH0TmHIk2/xnj2Eyw9152IfutIpOda3iswhjrx1LEkzUgdJ8bCdiebgg6QQ== + dependencies: + "@react-types/overlays" "^3.2.1" + "@react-types/shared" "^3.2.1" + +"@react-types/meter@^3.1.1": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@react-types/meter/-/meter-3.1.1.tgz#1a89c77c0f847fc741984703a22af266eae1429f" + integrity sha512-82dltyAhCIfyuwfyu+dijEUC08+G7imX3x7QVPSWIHfXusWbWXQG9YzBXJkmCoZlMPEMhEtA6l5niHM3gMD/Zg== + dependencies: + "@react-types/progress" "^3.1.1" + "@react-types/shared" "^3.2.1" + +"@react-types/overlays@^3.2.1", "@react-types/overlays@^3.4.0": + version "3.4.0" + resolved "https://registry.yarnpkg.com/@react-types/overlays/-/overlays-3.4.0.tgz#3c4619906bb12e3697e770b59c2090bb18da25bd" + integrity sha512-ddiMB6JXR7acQnRFEL2/6SSdBropmNrcAFk3qFCfovuVZh6STYhPmoAgj06mJFDoAD63pxayysfPG2EvLl2yAw== + dependencies: + "@react-types/shared" "^3.3.0" + +"@react-types/progress@^3.1.1": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@react-types/progress/-/progress-3.1.1.tgz#e2a99eab26e2b3117f65f78ccb320eae1cdbf693" + integrity sha512-Q9mgDbUw7Dcexd2CAo/NRanQ+7btHYAzjphoVSrIUwTsmgg4/WsPjZ3fplVyyRnzoYEjME/b7Og5HZ+ZEFTvsA== + dependencies: + "@react-types/shared" "^3.2.1" + +"@react-types/radio@^3.1.1": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@react-types/radio/-/radio-3.1.1.tgz#5b1b11ff3043ac902e8970e49260f2664da80e5e" + integrity sha512-neInMjlbZyyGYYyeDJk9BcEejLczvsBiyk/swSUHmQ99eNIjK3ptUHTNdXM1xBBc3zI1SvBxOQr+uGeeEszvxw== + dependencies: + "@react-types/shared" "^3.2.1" + +"@react-types/searchfield@^3.1.1": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@react-types/searchfield/-/searchfield-3.1.1.tgz#bbbb8984706c02559810328791cdfb8d418336a0" + integrity sha512-qNVrO3bIM9TcZHVuU7QI12LHShosvp3D297xw/iGLQoyaL0/W68d4dJs5ujU5ZRj8/gGRhAQiparpRs9hiHkxw== + dependencies: + "@react-types/textfield" "^3.2.1" + +"@react-types/select@^3.1.1", "@react-types/select@^3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@react-types/select/-/select-3.2.0.tgz#31b9e0f94fc24f053f4a1f073e174ffd59bac055" + integrity sha512-9vYhQWr1iB+3KWTZ1RxS2xZq0n0CJfsTRbEr0akLrtE/pRLC4O4l8RMFD49HyX0fShvz1FStmxTE2x7k8yVc4w== + dependencies: + "@react-types/shared" "^3.4.0" + +"@react-types/shared@^3.2.1", "@react-types/shared@^3.3.0", "@react-types/shared@^3.4.0": + version "3.4.0" + resolved "https://registry.yarnpkg.com/@react-types/shared/-/shared-3.4.0.tgz#a7cbf8c676b4b3b7b687bcdc8e44828c34d115f4" + integrity sha512-qYuL9JdIVC5JQmUgmurtm4JZQrg6IUy8wrMbaqNbt1e85Zg7A6ff1ffFrZ5IIgc1LDxYC7BB9KtL/bCgnjqrng== + +"@react-types/slider@^3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@react-types/slider/-/slider-3.0.1.tgz#b663c06765c5517f5d433e6158ad29d12eeaac4e" + integrity sha512-EUWogUMH/dU01+adJ7/Hlu6mP0thbXw8ftmWbPVMLWqweV2dEzRkvQZ8d9+q2JFMSNXwMSWvuMSVSnPKFbUXeQ== + dependencies: + "@react-types/shared" "^3.4.0" + +"@react-types/switch@^3.1.1": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@react-types/switch/-/switch-3.1.1.tgz#7909a8f7c2cb68ab7536efd03af3be3417e0eca3" + integrity sha512-nI5J/1CrJrVANwgikXyPMqxWJ4UyefzE4Vz/TwTgoXQ9v+LRNo22wbisfh1EmJAlZ0E52X/iKViVaBroNty+EA== + dependencies: + "@react-types/checkbox" "^3.2.1" + "@react-types/shared" "^3.2.1" + +"@react-types/textfield@^3.2.1", "@react-types/textfield@^3.2.2": + version "3.2.2" + resolved "https://registry.yarnpkg.com/@react-types/textfield/-/textfield-3.2.2.tgz#2f310c125df7c4a64a19d7c5064537218f909d38" + integrity sha512-S+U+Uc0WDgMK8X28j5WUtmkCL25iTQ+oGfCRFf4/GJtiwfO9lVLCgH/NWxpoVuNsPGvt36rlDnyS82Ge9H1/qA== + dependencies: + "@react-types/shared" "^3.2.1" + +"@react-types/tooltip@^3.1.1": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@react-types/tooltip/-/tooltip-3.1.1.tgz#7d45a4dd8c57c422a1a2dcb03b6c043e7481c3ca" + integrity sha512-18gM2Co9tzCDfN0tEdfboD18sXDtD6YiKctd8HQ8tBiRO4IF1ce9ubKe6++Lj+38GQPq7GWFFoUiS1WArTWIHA== + dependencies: + "@react-types/overlays" "^3.4.0" + "@react-types/shared" "^3.4.0" + "@rollup/plugin-babel@^5.2.0": version "5.2.3" resolved "https://registry.yarnpkg.com/@rollup/plugin-babel/-/plugin-babel-5.2.3.tgz#ee8fffbaa62a6c9ccd41b1bfca32e81f847700ee" @@ -5775,6 +6411,11 @@ clone@^1.0.2: resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= +clsx@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188" + integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA== + co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" @@ -6936,6 +7577,13 @@ dom-converter@^0.2: dependencies: utila "~0.4" +dom-helpers@^3.3.1: + version "3.4.0" + resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.4.0.tgz#e9b369700f959f62ecde5a6babde4bccd9169af8" + integrity sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA== + dependencies: + "@babel/runtime" "^7.1.2" + dom-serializer@0: version "0.2.2" resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" @@ -9975,6 +10623,11 @@ intl-locales-supported@~1.8.12: resolved "https://registry.yarnpkg.com/intl-locales-supported/-/intl-locales-supported-1.8.12.tgz#bbd83475a1cda61dc026309ca61f64c450af8ccb" integrity sha512-FJPl7p1LYO/C+LpwlDcvVpq7AeFTdFgwnq1JjdNYKjb51xkIxssXRR8LaA0fJFogjwRRztqw1ahgSJMSZsSFdw== +intl-messageformat-parser@1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/intl-messageformat-parser/-/intl-messageformat-parser-1.4.0.tgz#b43d45a97468cadbe44331d74bb1e8dea44fc075" + integrity sha1-tD1FqXRoytvkQzHXS7Ho3qRPwHU= + intl-messageformat-parser@^6.0.4: version "6.0.4" resolved "https://registry.yarnpkg.com/intl-messageformat-parser/-/intl-messageformat-parser-6.0.4.tgz#487a16ad58ee681ae67a3e86bae76ae7b7e7e03c" @@ -9982,6 +10635,13 @@ intl-messageformat-parser@^6.0.4: dependencies: "@formatjs/ecma402-abstract" "^1.1.0" +intl-messageformat@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-2.2.0.tgz#345bcd46de630b7683330c2e52177ff5eab484fc" + integrity sha1-NFvNRt5jC3aDMwwuUhd/9eq0hPw= + dependencies: + intl-messageformat-parser "1.4.0" + intl-messageformat@^9.3.5: version "9.3.5" resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-9.3.5.tgz#8b8fdfcf5d20e85682da24d4f709ef5903742310" @@ -14276,6 +14936,37 @@ rc@^1.0.1, rc@^1.1.6, rc@^1.2.7, rc@^1.2.8: minimist "^1.2.0" strip-json-comments "~2.0.1" +react-aria@~3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/react-aria/-/react-aria-3.4.0.tgz#904d7346a032970a0b4dc1904176ade96db5cdb2" + integrity sha512-PH8OFLe2xZGrIQfRIDLWHKUEog/UwE8H9L0MhYw9TmlJaW1Lc/ir69HiX/bOQJz6V/9XtDIKtNIXX3Fo1lsAJQ== + dependencies: + "@react-aria/breadcrumbs" "^3.1.2" + "@react-aria/button" "^3.3.1" + "@react-aria/checkbox" "^3.2.1" + "@react-aria/dialog" "^3.1.2" + "@react-aria/focus" "^3.2.3" + "@react-aria/i18n" "^3.3.0" + "@react-aria/interactions" "^3.3.3" + "@react-aria/label" "^3.1.1" + "@react-aria/link" "^3.1.2" + "@react-aria/listbox" "^3.2.4" + "@react-aria/menu" "^3.1.4" + "@react-aria/meter" "^3.1.1" + "@react-aria/overlays" "^3.6.1" + "@react-aria/progress" "^3.1.1" + "@react-aria/radio" "^3.1.3" + "@react-aria/searchfield" "^3.1.1" + "@react-aria/select" "^3.3.0" + "@react-aria/separator" "^3.1.1" + "@react-aria/slider" "^3.0.1" + "@react-aria/ssr" "^3.0.1" + "@react-aria/switch" "^3.1.1" + "@react-aria/textfield" "^3.2.2" + "@react-aria/tooltip" "^3.1.1" + "@react-aria/utils" "^3.6.0" + "@react-aria/visually-hidden" "^3.2.1" + react-color@^2.17.0: version "2.19.3" resolved "https://registry.yarnpkg.com/react-color/-/react-color-2.19.3.tgz#ec6c6b4568312a3c6a18420ab0472e146aa5683d"