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 (
-
+
{
const { group, item, removeItem } = props;
+ const { formatMessage } = useIntl();
const classes = mergeClasses(defaultClasses, props.classes);
const handleClick = useCallback(() => {
removeItem({ group, item });
}, [group, item, removeItem]);
+ const ariaLabel = formatMessage(
+ {
+ id: 'filterModal.action.clearFilterItem.ariaLabel',
+ defaultMessage: 'Clear filter'
+ },
+ {
+ name: item.title
+ }
+ );
+
return (
-
+
{item.title}
diff --git a/packages/venia-ui/lib/components/FilterModal/CurrentFilters/currentFilters.js b/packages/venia-ui/lib/components/FilterModal/CurrentFilters/currentFilters.js
index a2051738dd..86f0732ec8 100644
--- a/packages/venia-ui/lib/components/FilterModal/CurrentFilters/currentFilters.js
+++ b/packages/venia-ui/lib/components/FilterModal/CurrentFilters/currentFilters.js
@@ -4,11 +4,13 @@ import { shape, string } from 'prop-types';
import { mergeClasses } from '../../../classify';
import CurrentFilter from './currentFilter';
import defaultClasses from './currentFilters.css';
+import { useIntl } from 'react-intl';
const CurrentFilters = props => {
const { filterApi, filterState } = props;
const { removeItem } = filterApi;
const classes = mergeClasses(defaultClasses, props.classes);
+ const { formatMessage } = useIntl();
// create elements and params at the same time for efficiency
const filterElements = useMemo(() => {
@@ -33,7 +35,16 @@ const CurrentFilters = props => {
return elements;
}, [classes.item, filterState, removeItem]);
- return ;
+ const currentFiltersAriaLabel = formatMessage({
+ id: 'filterModal.currentFilters.ariaLabel',
+ defaultMessage: 'Current Filters'
+ });
+
+ return (
+
+ );
};
CurrentFilters.propTypes = {
diff --git a/packages/venia-ui/lib/components/FilterModal/FilterList/filterDefault.js b/packages/venia-ui/lib/components/FilterModal/FilterList/filterDefault.js
index 968ef03cec..49cac04c4f 100644
--- a/packages/venia-ui/lib/components/FilterModal/FilterList/filterDefault.js
+++ b/packages/venia-ui/lib/components/FilterModal/FilterList/filterDefault.js
@@ -1,4 +1,5 @@
import React from 'react';
+import { useIntl } from 'react-intl';
import { bool, shape, string } from 'prop-types';
import Checkbox from '../../Checkbox';
@@ -6,10 +7,37 @@ import { mergeClasses } from '../../../classify';
import defaultClasses from './filterDefault.css';
const FilterDefault = props => {
- const { classes: propsClasses, isSelected, item, ...restProps } = props;
+ const {
+ classes: propsClasses,
+ isSelected,
+ item,
+ isExpanded,
+ ...restProps
+ } = props;
const { label, value_index } = item || {};
+ const { formatMessage } = useIntl();
const classes = mergeClasses(defaultClasses, propsClasses);
+ const ariaLabel = !isSelected
+ ? formatMessage(
+ {
+ id: 'filterModal.item.applyFilter',
+ defaultMessage: 'Apply filter'
+ },
+ {
+ optionName: label
+ }
+ )
+ : formatMessage(
+ {
+ id: 'filterModal.item.clearFilter',
+ defaultMessage: 'Remove filter'
+ },
+ {
+ optionName: label
+ }
+ );
+
return (
{
fieldState={{
value: isSelected
}}
+ disabled={!isExpanded}
label={label}
+ ariaLabel={ariaLabel}
{...restProps}
/>
);
diff --git a/packages/venia-ui/lib/components/FilterModal/FilterList/filterItem.js b/packages/venia-ui/lib/components/FilterModal/FilterList/filterItem.js
index da5a5efab9..13090ca354 100644
--- a/packages/venia-ui/lib/components/FilterModal/FilterList/filterItem.js
+++ b/packages/venia-ui/lib/components/FilterModal/FilterList/filterItem.js
@@ -5,7 +5,7 @@ import setValidator from '@magento/peregrine/lib/validators/set';
import FilterDefault from './filterDefault';
const FilterItem = props => {
- const { filterApi, filterState, group, item } = props;
+ const { filterApi, filterState, group, item, isExpanded } = props;
const { toggleItem } = filterApi;
const { title, value } = item;
const isSelected = filterState && filterState.has(item);
@@ -26,6 +26,7 @@ const FilterItem = props => {
return (
{
- const { filterApi, filterState, group, items } = props;
+ const { filterApi, filterState, group, items, isExpanded } = props;
const classes = mergeClasses(defaultClasses, props.classes);
// memoize item creation
@@ -28,6 +28,7 @@ const FilterList = props => {
filterState={filterState}
group={group}
item={item}
+ isExpanded={isExpanded}
/>
);
@@ -38,7 +39,7 @@ const FilterList = props => {
return element;
}),
- [classes, filterApi, filterState, group, items]
+ [classes, filterApi, filterState, group, items, isExpanded]
);
return (
diff --git a/packages/venia-ui/lib/components/FilterModal/filterBlock.js b/packages/venia-ui/lib/components/FilterModal/filterBlock.js
index bbd7dfa22a..377320bab3 100644
--- a/packages/venia-ui/lib/components/FilterModal/filterBlock.js
+++ b/packages/venia-ui/lib/components/FilterModal/filterBlock.js
@@ -1,4 +1,5 @@
import React from 'react';
+import { useIntl } from 'react-intl';
import { arrayOf, shape, string } from 'prop-types';
import { ChevronDown as ArrowDown, ChevronUp as ArrowUp } from 'react-feather';
import { Form } from 'informed';
@@ -12,6 +13,7 @@ import defaultClasses from './filterBlock.css';
const FilterBlock = props => {
const { filterApi, filterState, group, items, name } = props;
+ const { formatMessage } = useIntl();
const talonProps = useFilterBlock();
const { handleClick, isExpanded } = talonProps;
const iconSrc = isExpanded ? ArrowUp : ArrowDown;
@@ -20,12 +22,44 @@ const FilterBlock = props => {
? classes.list_expanded
: classes.list_collapsed;
+ const itemAriaLabel = formatMessage(
+ {
+ id: 'filterModal.item.ariaLabel',
+ defaultMessage: 'Filter products by'
+ },
+ {
+ itemName: name
+ }
+ );
+
+ const toggleItemOptionsAriaLabel = isExpanded
+ ? formatMessage(
+ {
+ id: 'filterModal.item.hideOptions',
+ defaultMessage: 'Hide filter item options.'
+ },
+ {
+ itemName: name
+ }
+ )
+ : formatMessage(
+ {
+ id: 'filterModal.item.showOptions',
+ defaultMessage: 'Show filter item options.'
+ },
+ {
+ itemName: name
+ }
+ );
+
return (
-
+
{name}
@@ -38,6 +72,7 @@ const FilterBlock = props => {
filterState={filterState}
group={group}
items={items}
+ isExpanded={isExpanded}
/>
diff --git a/packages/venia-ui/lib/components/FilterModal/filterFooter.js b/packages/venia-ui/lib/components/FilterModal/filterFooter.js
index e9dca7b63a..c7a551957e 100644
--- a/packages/venia-ui/lib/components/FilterModal/filterFooter.js
+++ b/packages/venia-ui/lib/components/FilterModal/filterFooter.js
@@ -1,5 +1,5 @@
import React from 'react';
-import { FormattedMessage } from 'react-intl';
+import { useIntl } from 'react-intl';
import { bool, func, shape, string } from 'prop-types';
import { useFilterFooter } from '@magento/peregrine/lib/talons/FilterModal';
@@ -9,19 +9,27 @@ import defaultClasses from './filterFooter.css';
const FilterFooter = props => {
const { applyFilters, hasFilters, isOpen } = props;
+ const { formatMessage } = useIntl();
const { touched } = useFilterFooter({
hasFilters,
isOpen
});
const classes = mergeClasses(defaultClasses, props.classes);
+ const buttonLabel = formatMessage({
+ id: 'filterFooter.results',
+ defaultMessage: 'See Results'
+ });
return (
-
-
+
+ {buttonLabel}
);
diff --git a/packages/venia-ui/lib/components/FilterModal/filterModal.js b/packages/venia-ui/lib/components/FilterModal/filterModal.js
index 8c381cde69..7547bdbae0 100644
--- a/packages/venia-ui/lib/components/FilterModal/filterModal.js
+++ b/packages/venia-ui/lib/components/FilterModal/filterModal.js
@@ -1,5 +1,6 @@
import React, { useMemo } from 'react';
-import { FormattedMessage } from 'react-intl';
+import { FormattedMessage, useIntl } from 'react-intl';
+import { FocusScope } from 'react-aria';
import { array, arrayOf, shape, string } from 'prop-types';
import { X as CloseIcon } from 'react-feather';
import { useFilterModal } from '@magento/peregrine/lib/talons/FilterModal';
@@ -20,6 +21,7 @@ import defaultClasses from './filterModal.css';
*/
const FilterModal = props => {
const { filters } = props;
+ const { formatMessage } = useIntl();
const talonProps = useFilterModal({ filters });
const {
filterApi,
@@ -29,6 +31,7 @@ const FilterModal = props => {
handleApply,
handleClose,
handleReset,
+ handleKeyDownActions,
isOpen
} = talonProps;
@@ -55,9 +58,28 @@ const FilterModal = props => {
[filterApi, filterItems, filterNames, filterState]
);
+ const filtersAriaLabel = formatMessage({
+ id: 'filterModal.filters.ariaLabel',
+ defaultMessage: 'Filters'
+ });
+
+ const closeAriaLabel = formatMessage({
+ id: 'filterModal.filters.close.ariaLabel',
+ defaultMessage: 'Close filters popup.'
+ });
+
+ const clearAllAriaLabel = formatMessage({
+ id: 'filterModal.action.clearAll.ariaLabel',
+ defaultMessage: 'Clear all applied filters'
+ });
+
const clearAll = filterState.size ? (
-
+
{
) : null;
+ if (!isOpen) {
+ return null;
+ }
+
return (
-
-
-
-
-
-
-
-
-
+ {/* eslint-disable-next-line jsx-a11y/no-autofocus */}
+
+ {/* eslint-disable-next-line jsx-a11y/no-static-element-interactions */}
+
+
+
+
+
+
+
+
+
+
+
+ {clearAll}
+
-
- {clearAll}
-
-
-
-
+
+
);
};
diff --git a/packages/venia-ui/lib/components/FilterModalOpenButton/filterModalOpenButton.css b/packages/venia-ui/lib/components/FilterModalOpenButton/filterModalOpenButton.css
new file mode 100644
index 0000000000..588ca7de5c
--- /dev/null
+++ b/packages/venia-ui/lib/components/FilterModalOpenButton/filterModalOpenButton.css
@@ -0,0 +1,4 @@
+.filterButton {
+ composes: root_lowPriority from '../../components/Button/button.css';
+ min-width: 6.25rem;
+}
diff --git a/packages/venia-ui/lib/components/FilterModalOpenButton/filterModalOpenButton.js b/packages/venia-ui/lib/components/FilterModalOpenButton/filterModalOpenButton.js
new file mode 100644
index 0000000000..b231b56ed0
--- /dev/null
+++ b/packages/venia-ui/lib/components/FilterModalOpenButton/filterModalOpenButton.js
@@ -0,0 +1,38 @@
+import React from 'react';
+import { shape, string, array } from 'prop-types';
+import { FormattedMessage } from 'react-intl';
+import Button from '../Button';
+import { mergeClasses } from '../../classify';
+import defaultClasses from './filterModalOpenButton.css';
+import { useFilterModal } from '@magento/peregrine/lib/talons/FilterModal';
+
+const FilterModalOpenButton = props => {
+ const { filters, classes: propsClasses } = props;
+ const classes = mergeClasses(defaultClasses, propsClasses);
+ const { handleOpen } = useFilterModal({ filters });
+
+ return (
+
+
+
+ );
+};
+
+export default FilterModalOpenButton;
+
+FilterModalOpenButton.propTypes = {
+ filters: array,
+ classes: shape({
+ filterButton: string
+ })
+};
diff --git a/packages/venia-ui/lib/components/FilterModalOpenButton/index.js b/packages/venia-ui/lib/components/FilterModalOpenButton/index.js
new file mode 100644
index 0000000000..710851c701
--- /dev/null
+++ b/packages/venia-ui/lib/components/FilterModalOpenButton/index.js
@@ -0,0 +1 @@
+export { default } from './filterModalOpenButton';
diff --git a/packages/venia-ui/lib/components/SearchPage/__tests__/__snapshots__/searchPage.spec.js.snap b/packages/venia-ui/lib/components/SearchPage/__tests__/__snapshots__/searchPage.spec.js.snap
index d70f7ac46f..becaf11954 100644
--- a/packages/venia-ui/lib/components/SearchPage/__tests__/__snapshots__/searchPage.spec.js.snap
+++ b/packages/venia-ui/lib/components/SearchPage/__tests__/__snapshots__/searchPage.spec.js.snap
@@ -52,14 +52,33 @@ exports[`Search Page Component error view does not render when data is present 1
`;
exports[`Search Page Component error view renders when data is not present and not loading 1`] = `
-
+
-
+
+
+
+
`;
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 (
-
+
{children}
);
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"