diff --git a/.changeset/tame-mayflies-move.md b/.changeset/tame-mayflies-move.md new file mode 100644 index 0000000000..ce3fc78355 --- /dev/null +++ b/.changeset/tame-mayflies-move.md @@ -0,0 +1,5 @@ +--- +'@sumup/circuit-ui': major +--- + +Replaced the old Popover component with a new one. It uses Popper v2 and comes with a refreshed component API. diff --git a/packages/circuit-ui/components/Popover/Popover.docs.mdx b/packages/circuit-ui/components/Popover/Popover.docs.mdx new file mode 100644 index 0000000000..3a26fb50f8 --- /dev/null +++ b/packages/circuit-ui/components/Popover/Popover.docs.mdx @@ -0,0 +1,23 @@ +import { Status, Props, Story } from '../../../../.storybook/components'; +import { Popover } from '@sumup/circuit-ui'; + +# Popover + +Popover menus are a common pattern to display a list of subsequent action options, when interacting with an actionable component. + + + + +- Triggers of Popover can be primary, secondary, tertiary buttons, an overflow icon, or components with embedded buttons such as the [ImageInput component](Forms/ImageInput). +- Each Popover action item is represented by an appropriate HTML element (button or a). +- If needed the dividing line can be used to separate Popover action items. +- The leading icon is optional. +- The Popover is powered by React Popper [https://popper.js.org/docs/v2/] which means you can easily change the Popover placement by simply passing the placement prop. + +## Usage guidelines + +- **Do** use clear, concise and actionable labels for Popover items +- **Do** always think about the priority of the action option to be taken and put the option order in logical order + + + diff --git a/packages/circuit-ui/components/Popover/Popover.js b/packages/circuit-ui/components/Popover/Popover.js deleted file mode 100644 index a2cae2d94d..0000000000 --- a/packages/circuit-ui/components/Popover/Popover.js +++ /dev/null @@ -1,263 +0,0 @@ -/** - * Copyright 2019, SumUp Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React, { Component } from 'react'; -import PropTypes from 'prop-types'; -import { Manager, Reference, Popper } from 'react-popper'; -import styled from '@emotion/styled'; -import { css } from '@emotion/core'; - -import Portal from '../Portal'; -import { positionPropType, alignPropType } from '../../util/shared-prop-types'; - -import { toPopperPlacement, popperModifiers } from './PopoverService'; - -const ReferenceWrapper = styled('div')` - label: popover__button-wrapper; - display: inline-block; - - &:focus { - outline: none; - } - - ${({ referenceWrapperStyles, ...rest }) => referenceWrapperStyles(rest)}; -`; - -const basePopoverWrapperStyles = ({ theme }) => css` - label: popover; - z-index: ${theme.zIndex.popover}; -`; - -const customZIndexWrapperStyles = ({ zIndex }) => - zIndex && - css` - z-index: ${zIndex}; - `; - -const PopoverWrapper = styled('div')( - basePopoverWrapperStyles, - customZIndexWrapperStyles, -); - -const arrowUpStyles = css` - position: absolute; - top: 0; - left: 50%; - transform: translate(-50%, -100%); -`; - -const arrowDownStyles = css` - position: absolute; - bottom: 0; - left: 50%; - transform: translate(-50%, 100%); -`; - -const arrowLeftStyles = css` - position: absolute; - left: 0; - top: 50%; - transform: translate(-100%, -50%); -`; - -const arrowRightStyles = css` - position: absolute; - right: 0; - top: 50%; - transform: translate(100%, -50%); -`; - -const oppositeDirection = { - left: 'right', - right: 'left', - top: 'down', - bottom: 'up', -}; - -const arrowStyles = { - up: arrowUpStyles, - down: arrowDownStyles, - left: arrowLeftStyles, - right: arrowRightStyles, -}; - -class Popover extends Component { - static propTypes = { - /** - * isOpen controlled prop - */ - isOpen: PropTypes.bool, - /** - * function rendering the popover - */ - renderPopover: PropTypes.func.isRequired, - /** - * function rendering the reference (button or something clickable) - */ - renderReference: PropTypes.func, - /** - * placement of the popover relative to the reference - */ - position: positionPropType, - /** - * alignment of the popover relative to the reference - */ - align: alignPropType, - /** - * A callback that is called when the popover should be closed when reference is clicked in an open state - */ - onReferenceClickClose: PropTypes.func.isRequired, - /** - * A callback that is called on click outside the popover wrapper or the reference - */ - onOutsideClickClose: PropTypes.func.isRequired, - /** - * A custom z-index for the popover - */ - zIndex: PropTypes.number, - onClose: PropTypes.func, - usePortal: PropTypes.bool, - modifiers: PropTypes.shape(), - arrowRenderer: PropTypes.func, - referenceWrapperStyles: PropTypes.func, - referenceElement: PropTypes.element, - }; - - static defaultProps = { - isOpen: false, - position: 'bottom', - align: 'start', - zIndex: null, - onClose: () => {}, - usePortal: false, - modifiers: {}, - arrowRenderer: () => null, - renderReference: () => null, - referenceElement: null, - referenceWrapperStyles: () => null, - }; - - buttonRef = null; - - popoverRef = null; - - componentDidMount() { - document.addEventListener('click', this.handleDocumentClick, true); - } - - componentWillUnmount() { - document.removeEventListener('click', this.handleDocumentClick, true); - } - - handleDocumentClick = ({ target }) => { - const isWithinPopover = this.popoverRef && this.popoverRef.contains(target); - const isWithinButton = this.buttonRef && this.buttonRef.contains(target); - - if (this.props.isOpen && !isWithinButton && !isWithinPopover) { - this.props.onOutsideClickClose(target); - } - }; - - receiveButtonRef = (ref) => { - this.buttonRef = ref; - }; - - receivePopoverRef = (ref) => { - this.popoverRef = ref; - }; - - handleReferenceClick = () => { - const { isOpen } = this.props; - if (isOpen) { - this.props.onReferenceClickClose(); - } - }; - - render() { - const { - arrowRenderer, - renderPopover, - renderReference, - referenceElement, - referenceWrapperStyles, - position, - align, - isOpen, - zIndex, - modifiers, - usePortal, - ...props - } = this.props; - - const reference = !referenceElement && ( - - {({ ref }) => ( - -
{renderReference()}
-
- )} -
- ); - - const popper = isOpen && ( - - {({ ref, style }) => - isOpen && ( - -
- {renderPopover()} - {!!arrowRenderer && - arrowRenderer( - arrowStyles[oppositeDirection[position]], - oppositeDirection[position], - )} -
-
- ) - } -
- ); - - return ( - - {reference} - {usePortal ? {popper} : popper} - - ); - } -} - -/** - * @component - */ -export default Popover; diff --git a/packages/circuit-ui/components/Popover/Popover.spec.js b/packages/circuit-ui/components/Popover/Popover.spec.js deleted file mode 100644 index d77831d7d3..0000000000 --- a/packages/circuit-ui/components/Popover/Popover.spec.js +++ /dev/null @@ -1,116 +0,0 @@ -/** - * Copyright 2019, SumUp Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React from 'react'; - -import Popover from '.'; - -const positions = ['top', 'bottom', 'left', 'right']; -const alignments = ['start', 'end', 'center']; - -const defaultProps = { - // eslint-disable-next-line react/display-name - renderReference: () => , - // eslint-disable-next-line react/display-name - renderPopover: () =>
, - onReferenceClickClose: () => {}, - onOutsideClickClose: () => {}, -}; - -// FMI: https://github.com/FezVrasta/popper.js/issues/478 -jest.mock('popper.js', () => { - const PopperJS = jest.requireActual('popper.js'); - - return class Popper { - static placements = PopperJS.placements; - - constructor() { - return { - destroy: () => {}, - scheduleUpdate: () => {}, - }; - } - }; -}); - -describe('Popover', () => { - beforeEach(() => { - jest.resetAllMocks(); - }); - - /** - * Style tests. - */ - it('should render with default styles', () => { - const actual = create(); - expect(actual).toMatchSnapshot(); - }); - - positions.forEach((position) => { - alignments.forEach((alignment) => { - it(`should render with position ${position} and alignment ${alignment}`, () => { - const actual = create( - , - ); - expect(actual).toMatchSnapshot(); - }); - }); - }); - - it('should render nothing without isOpen=false', () => { - const { queryByTestId } = render( - , - ); - expect(queryByTestId('popover-child')).toBeNull(); - }); - - it('should call onReferenceClickClose on clicked reference when isOpen=true', () => { - const onReferenceClickClose = jest.fn(); - const { getByTestId } = render( - , - ); - - act(() => { - fireEvent.click(getByTestId('popover-reference')); - }); - - expect(onReferenceClickClose).toHaveBeenCalledTimes(1); - }); - - it('should not render component when referenceElement is passed', () => { - const { queryByTestId } = render( - } />, - ); - expect(queryByTestId('popover-reference')).toBeNull(); - }); - - /** - * Accessibility tests. - */ - it('should meet accessibility guidelines', async () => { - const wrapper = renderToHtml(); - const actual = await axe(wrapper); - expect(actual).toHaveNoViolations(); - }); -}); diff --git a/packages/circuit-ui/components/Popover/Popover.spec.tsx b/packages/circuit-ui/components/Popover/Popover.spec.tsx new file mode 100644 index 0000000000..aff17dad74 --- /dev/null +++ b/packages/circuit-ui/components/Popover/Popover.spec.tsx @@ -0,0 +1,167 @@ +/** + * Copyright 2020, SumUp Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { CirclePlus, Zap } from '@sumup/icons'; +import React, { useRef } from 'react'; +import { Placement } from '@popperjs/core'; + +import { + create, + renderToHtml, + axe, + RenderFn, + render, + userEvent, +} from '../../util/test-utils'; + +import { + PopoverItem, + PopoverItemProps, + Popover, + PopoverProps, +} from './Popover'; + +const placements: Placement[] = ['auto', 'top', 'bottom', 'left', 'right']; + +describe('PopoverItem', () => { + function renderPopoverItem( + renderFn: RenderFn, + props: PopoverItemProps, + ) { + return renderFn(); + } + + const baseProps = { children: 'PopoverItem' }; + + describe('styles', () => { + it('should render as Link when an href (and onClick) is passed', () => { + const props = { + ...baseProps, + href: 'https://sumup.com', + onClick: jest.fn(), + icon: Zap, + }; + const { container } = renderPopoverItem(render, props); + const anchorEl = container.querySelector('a'); + expect(anchorEl).toBeVisible(); + }); + + it('should render as a `button` when an onClick is passed', () => { + const props = { ...baseProps, onClick: jest.fn(), icon: Zap }; + const { container } = renderPopoverItem(render, props); + const buttonEl = container.querySelector('button'); + expect(buttonEl).toBeVisible(); + }); + }); + + describe('accessibility', () => { + it('should meet accessibility guidelines', async () => { + const props = { + ...baseProps, + href: 'https://sumup.com', + onClick: jest.fn(), + icon: Zap, + }; + const wrapper = renderPopoverItem(renderToHtml, props); + const actual = await axe(wrapper); + expect(actual).toHaveNoViolations(); + }); + }); + + describe('business logic', () => { + it('should call onClick when rendered as Link', () => { + const props = { + ...baseProps, + href: 'https://sumup.com', + onClick: jest.fn(), + icon: Zap, + }; + const { container } = renderPopoverItem(render, props); + const anchorEl = container.querySelector('a'); + if (anchorEl) { + userEvent.click(anchorEl); + } + expect(props.onClick).toHaveBeenCalledTimes(1); + }); + }); +}); + +describe('Popover', () => { + const Default = (props: Omit) => { + const triggerRef = useRef(null); + + return ( + <> + + + + ); + }; + + const baseProps = { + actions: [ + { + onClick: () => alert('Hello'), + children: 'Add', + icon: CirclePlus, + }, + ], + isOpen: true, + onClose: jest.fn(), + }; + + describe('styles', () => { + it('should render with default styles', () => { + const actual = create(); + expect(actual).toMatchSnapshot(); + }); + + placements.forEach((placement) => { + it(`should render popover on ${placement}`, () => { + const actual = create(); + expect(actual).toMatchSnapshot(); + }); + }); + }); + + describe('business logic', () => { + it('should close popover when passing a click outside', () => { + const { queryByText } = render(); + expect(queryByText('Add')).not.toBeNull(); + + userEvent.click(document.body); + + expect(baseProps.onClose).toHaveBeenCalledTimes(1); + }); + + it('should close popover when passing a click to a reference element', () => { + const { queryByText, getAllByRole } = render(); + expect(queryByText('Add')).not.toBeNull(); + + userEvent.click(getAllByRole('button')[0]); + + expect(baseProps.onClose).toHaveBeenCalledTimes(1); + }); + }); + + /** + * Accessibility tests. + */ + it('should meet accessibility guidelines', async () => { + const wrapper = renderToHtml(); + const actual = await axe(wrapper); + expect(actual).toHaveNoViolations(); + }); +}); diff --git a/packages/circuit-ui/components/Popover/Popover.stories.js b/packages/circuit-ui/components/Popover/Popover.stories.js deleted file mode 100644 index 2526b0f5ff..0000000000 --- a/packages/circuit-ui/components/Popover/Popover.stories.js +++ /dev/null @@ -1,81 +0,0 @@ -/** - * Copyright 2019, SumUp Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React, { useState } from 'react'; -import { findByText } from '@testing-library/dom'; -import userEvent from '@testing-library/user-event'; - -import Button from '../Button'; -import Card from '../Card'; - -import Popover from './Popover'; - -const interactionTasks = [ - { - name: 'Open popover', - description: - 'Click the popover and wait until the popover content is shown.', - run: async ({ container }) => { - const button = container.querySelector('[data-testid=button]'); - userEvent.click(button); - await findByText(container, 'Popover Content'); - }, - }, -]; - -export default { - title: 'Components/Popover', - component: Popover, - parameters: { - performance: { - interactions: interactionTasks, - }, - }, -}; - -export const Base = (args) => { - const [open, setOpen] = useState(false); - - const { closeOnButtonClick, ...props } = args; - - return ( - Popover Content} - renderReference={() => ( - - )} - onReferenceClickClose={() => { - if (closeOnButtonClick) { - setOpen(false); - } - }} - onOutsideClickClose={() => setOpen(false)} - /> - ); -}; - -Base.args = { - position: 'bottom', - align: 'start', - closeOnButtonClick: false, -}; diff --git a/packages/circuit-ui/components/Popover/Popover.stories.tsx b/packages/circuit-ui/components/Popover/Popover.stories.tsx new file mode 100644 index 0000000000..2ed8261161 --- /dev/null +++ b/packages/circuit-ui/components/Popover/Popover.stories.tsx @@ -0,0 +1,150 @@ +/** + * Copyright 2019, SumUp Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React, { useState, useRef } from 'react'; +import { action } from '@storybook/addon-actions'; +import { + More, + ThumbUp, + Zap, + CirclePlus, + PenStroke, + Share, + Bin, +} from '@sumup/icons'; + +import Button from '../Button'; +import IconButton from '../IconButton'; + +import { Popover, PopoverItem } from './Popover'; +import docs from './Popover.docs.mdx'; + +export default { + title: 'Components/Popover', + component: Popover, + parameters: { + docs: { page: docs }, + }, + argTypes: { + children: { control: 'text' }, + }, +}; +export const PopoverBase = (args) => { + const triggerRef = useRef(null); + + return ( + <> + + + + ); +}; + +PopoverBase.args = { + actions: [ + { + onClick: action('Button Click'), + href: '', + children: 'Label', + icon: Zap, + }, + { + onClick: action('Button Click'), + href: 'https://sumup.com/', + children: 'Label', + icon: Zap, + }, + { type: 'divider' }, + { + onClick: action('Button Click'), + children: 'Label', + icon: Zap, + destructive: true, + }, + ], +}; + +export const PopoverInteractive = (args) => { + const [isOpen, setOpen] = useState(false); + const triggerRef = useRef(null); + + const handleClick = () => { + setOpen((prev) => !prev); + }; + + const onClose = () => { + setOpen(false); + }; + + return ( + <> + + + + + + ); +}; + +PopoverInteractive.args = { + actions: [ + { + onClick: action('Button Click'), + href: '', + children: 'Add', + icon: CirclePlus, + }, + { + onClick: action('Button Click'), + href: 'https://sumup.com/', + children: 'Edit', + icon: PenStroke, + }, + { + onClick: action('Button Click'), + href: 'https://sumup.com/', + children: 'Upload', + icon: Share, + }, + { type: 'divider' }, + { + onClick: action('Button Click'), + children: 'Delete', + icon: Bin, + destructive: true, + }, + ], +}; + +export const PopoverItemBase = (args) => ; + +PopoverItemBase.args = { + onClick: action('Button Click'), + href: 'https://sumup.com/', + children: 'Label', + icon: Zap, +}; diff --git a/packages/circuit-ui/components/Popover/Popover.tsx b/packages/circuit-ui/components/Popover/Popover.tsx new file mode 100644 index 0000000000..ebb0765cbc --- /dev/null +++ b/packages/circuit-ui/components/Popover/Popover.tsx @@ -0,0 +1,294 @@ +/** + * Copyright 2021, SumUp Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** @jsx jsx */ +import { css, jsx } from '@emotion/core'; +import { Theme } from '@sumup/design-tokens'; +import React, { + useState, + FC, + HTMLProps, + SVGProps, + MouseEvent, + Fragment, + useMemo, + RefObject, +} from 'react'; +import { useClickAway, useLatest } from 'react-use'; +import { Dispatch as TrackingProps } from '@sumup/collector'; +import { usePopper } from 'react-popper'; +import { Placement, State, Modifier } from '@popperjs/core'; +import { useTheme } from 'emotion-theming'; + +import styled, { StyleProps } from '../../styles/styled'; +import { listItem, shadow, typography } from '../../styles/style-mixins'; +import { useComponents } from '../ComponentsContext'; +import useClickHandler from '../../hooks/use-click-handler'; +import Hr from '../Hr'; + +export interface BaseProps { + /** + * The Popover item label. + */ + children: string; + /** + * Function that's called when the item is clicked. + */ + onClick?: (event: MouseEvent | KeyboardEvent) => void; + /** + * Display an icon in addition to the label. + */ + icon?: FC>; + /** + * Destructive variant, changes the color of label and icon from blue to red to signal to the user that the action + * is irreversible or otherwise dangerous. Interactive states are the same for destructive variant. + */ + destructive?: boolean; + /** + * Additional data that is dispatched with the tracking event. + */ + tracking?: TrackingProps; + /** + * The ref to the HTML DOM element, can be a button or an anchor. + */ + ref?: React.Ref; +} + +type LinkElProps = Omit< + HTMLProps, + 'size' | 'type' | 'onClick' +>; +type ButtonElProps = Omit< + HTMLProps, + 'size' | 'type' | 'onClick' +>; + +export type PopoverItemProps = BaseProps & LinkElProps & ButtonElProps; +type PopoverItemWrapperProps = LinkElProps & ButtonElProps; + +const itemWrapperStyles = () => css` + label: popover-item; + display: flex; + justify-content: flex-start; + align-items: center; + width: 100%; +`; + +const PopoverItemWrapper = styled('button')( + listItem, + itemWrapperStyles, + typography('one'), +); + +const iconStyles = (theme: Theme) => css` + label: popover__icon; + margin-right: ${theme.spacings.byte}; +`; + +export const PopoverItem = ({ + children, + icon: Icon, + onClick, + tracking, + ...props +}: PopoverItemProps): JSX.Element => { + const components = useComponents(); + + // Need to typecast here because the PopoverItemWrapper expects a button-like + // component for its `as` prop. It's safe to ignore that constraint here. + /* eslint-disable @typescript-eslint/no-unsafe-assignment */ + const Link = components.Link as any; + + const handleClick = useClickHandler( + onClick, + tracking, + 'popover-item', + ); + + return ( + + {Icon && } + {children} + + ); +}; + +const wrapperStyles = ({ theme }: StyleProps) => css` + label: popover; + padding: ${theme.spacings.byte} 0px; + border: 1px solid ${theme.colors.n200}; + box-sizing: border-box; + border-radius: ${theme.borderRadius.byte}; + background-color: ${theme.colors.white}; + + ${theme.mq.untilKilo} { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; + } +`; + +const PopoverWrapper = styled('div')(wrapperStyles, shadow); + +const dividerStyles = (theme: Theme) => css` + margin: ${theme.spacings.byte} ${theme.spacings.mega}; + width: calc(100% - ${theme.spacings.mega}*2); +`; + +const Overlay = styled.div( + ({ theme }: StyleProps) => css` + ${theme.mq.untilKilo} { + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; + background-color: ${theme.colors.overlay}; + pointer-events: none; + } + `, +); + +type Divider = { type: 'divider' }; +type Action = PopoverItemProps | Divider; + +function isDivider(action: Action): action is Divider { + return 'type' in action && action.type === 'divider'; +} + +export interface PopoverProps { + /** + * Determine whether the Popover is opened or closed. + */ + isOpen: boolean; + /** + * An array of PopoverItem or Divider. + */ + actions: Action[]; + /** + * The reference to the element that toggles the Popover. + */ + triggerRef: RefObject; + /** + * One of the accepted placement values. Defaults to bottom. + */ + placement?: Placement; + /** + * The placements to fallback to when there is not enough space for the Popover. Defaults to ['top', 'right', 'left']. + */ + fallbackPlacements?: Placement[]; + /** + * Function that is called when closing the Popover. + */ + onClose: (event: Event) => void; +} + +export const Popover = ({ + isOpen, + onClose, + actions, + triggerRef, + placement = 'bottom', + fallbackPlacements = ['top', 'right', 'left'], + ...props +}: PopoverProps): JSX.Element | null => { + const theme: Theme = useTheme(); + + // Popper custom modifier to apply bottom sheet for mobile. + // The window.matchMedia() is a useful API for this, it allows you to change the styles based on a condition. + // useMemo hook is used in order to prevent the render loop, more https://popper.js.org/react-popper/v2/faq/#why-i-get-render-loop-whenever-i-put-a-function-inside-the-popper-configuration + const mobilePosition: Modifier<'mobilePosition', { state: State }> = useMemo( + () => ({ + name: 'mobilePosition', + enabled: true, + phase: 'write', + fn({ state }) { + if (window.matchMedia(`${theme.breakpoints.untilKilo}`).matches) { + // eslint-disable-next-line no-param-reassign + state.styles.popper = { + width: '100%', + left: '0px', + right: '0px', + bottom: '0px', + position: 'fixed', + }; + } else { + // eslint-disable-next-line no-param-reassign + state.styles.popper.width = 'auto'; + } + }, + }), + [theme], + ); + + // The flip modifier is used if the popper has placement set to bottom, but there isn't enough space to position the popper in that direction. + // By default, it will change the popper placement to top. More at https://popper.js.org/docs/v2/modifiers/flip/ + const flip = { + name: 'flip', + options: { + fallbackPlacements, + }, + }; + + // Note: the usePopper hook intentionally takes the DOM node, not refs, in order to be able to update when the nodes change. + // A callback ref is used here to permit this behaviour, and useState is an appropriate way to implement this. + const [popperElement, setPopperElement] = useState(null); + const { styles, attributes } = usePopper(triggerRef.current, popperElement, { + placement, + modifiers: [mobilePosition, flip], + }); + + // This is a performance optimization to prevent event listeners from being + // re-attached on every render. + const popperRef = useLatest(popperElement); + + useClickAway(popperRef, (event) => { + // The reference element has its own click handler to toggle the popover. + if ( + !triggerRef.current || + triggerRef.current.contains(event.target as Node) + ) { + return; + } + onClose(event); + }); + + if (!isOpen) { + return null; + } + + return ( + + + + {actions.map((action, index) => + isDivider(action) ? ( +
+ ) : ( + + ), + )} +
+
+ ); +}; diff --git a/packages/circuit-ui/components/Popover/PopoverService.js b/packages/circuit-ui/components/Popover/PopoverService.js deleted file mode 100644 index 6d4831cbf0..0000000000 --- a/packages/circuit-ui/components/Popover/PopoverService.js +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Copyright 2019, SumUp Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// popper.js modifiers -// read more: https://popper.js.org/popper-documentation.html#modifiers -export const popperModifiers = { - offset: { enabled: true, offset: '0,10' }, - flip: { enabled: true }, -}; - -export function toPopperPlacement(placement, align) { - return placement + (align !== 'center' ? `-${align}` : ''); -} diff --git a/packages/circuit-ui/components/Popover/__snapshots__/Popover.spec.js.snap b/packages/circuit-ui/components/Popover/__snapshots__/Popover.spec.js.snap deleted file mode 100644 index b3835fdb0e..0000000000 --- a/packages/circuit-ui/components/Popover/__snapshots__/Popover.spec.js.snap +++ /dev/null @@ -1,443 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Popover should render with default styles 1`] = ` -HTMLCollection [ - .circuit-0 { - display: inline-block; -} - -.circuit-0:focus { - outline: none; -} - -
-
- -
-
, - .circuit-0 { - z-index: 30; -} - -
-
-
-
-
, -] -`; - -exports[`Popover should render with position bottom and alignment center 1`] = ` -HTMLCollection [ - .circuit-0 { - display: inline-block; -} - -.circuit-0:focus { - outline: none; -} - -
-
- -
-
, - .circuit-0 { - z-index: 30; -} - -
-
-
-
-
, -] -`; - -exports[`Popover should render with position bottom and alignment end 1`] = ` -HTMLCollection [ - .circuit-0 { - display: inline-block; -} - -.circuit-0:focus { - outline: none; -} - -
-
- -
-
, - .circuit-0 { - z-index: 30; -} - -
-
-
-
-
, -] -`; - -exports[`Popover should render with position bottom and alignment start 1`] = ` -HTMLCollection [ - .circuit-0 { - display: inline-block; -} - -.circuit-0:focus { - outline: none; -} - -
-
- -
-
, - .circuit-0 { - z-index: 30; -} - -
-
-
-
-
, -] -`; - -exports[`Popover should render with position left and alignment center 1`] = ` -HTMLCollection [ - .circuit-0 { - display: inline-block; -} - -.circuit-0:focus { - outline: none; -} - -
-
- -
-
, - .circuit-0 { - z-index: 30; -} - -
-
-
-
-
, -] -`; - -exports[`Popover should render with position left and alignment end 1`] = ` -HTMLCollection [ - .circuit-0 { - display: inline-block; -} - -.circuit-0:focus { - outline: none; -} - -
-
- -
-
, - .circuit-0 { - z-index: 30; -} - -
-
-
-
-
, -] -`; - -exports[`Popover should render with position left and alignment start 1`] = ` -HTMLCollection [ - .circuit-0 { - display: inline-block; -} - -.circuit-0:focus { - outline: none; -} - -
-
- -
-
, - .circuit-0 { - z-index: 30; -} - -
-
-
-
-
, -] -`; - -exports[`Popover should render with position right and alignment center 1`] = ` -HTMLCollection [ - .circuit-0 { - display: inline-block; -} - -.circuit-0:focus { - outline: none; -} - -
-
- -
-
, - .circuit-0 { - z-index: 30; -} - -
-
-
-
-
, -] -`; - -exports[`Popover should render with position right and alignment end 1`] = ` -HTMLCollection [ - .circuit-0 { - display: inline-block; -} - -.circuit-0:focus { - outline: none; -} - -
-
- -
-
, - .circuit-0 { - z-index: 30; -} - -
-
-
-
-
, -] -`; - -exports[`Popover should render with position right and alignment start 1`] = ` -HTMLCollection [ - .circuit-0 { - display: inline-block; -} - -.circuit-0:focus { - outline: none; -} - -
-
- -
-
, - .circuit-0 { - z-index: 30; -} - -
-
-
-
-
, -] -`; - -exports[`Popover should render with position top and alignment center 1`] = ` -HTMLCollection [ - .circuit-0 { - display: inline-block; -} - -.circuit-0:focus { - outline: none; -} - -
-
- -
-
, - .circuit-0 { - z-index: 30; -} - -
-
-
-
-
, -] -`; - -exports[`Popover should render with position top and alignment end 1`] = ` -HTMLCollection [ - .circuit-0 { - display: inline-block; -} - -.circuit-0:focus { - outline: none; -} - -
-
- -
-
, - .circuit-0 { - z-index: 30; -} - -
-
-
-
-
, -] -`; - -exports[`Popover should render with position top and alignment start 1`] = ` -HTMLCollection [ - .circuit-0 { - display: inline-block; -} - -.circuit-0:focus { - outline: none; -} - -
-
- -
-
, - .circuit-0 { - z-index: 30; -} - -
-
-
-
-
, -] -`; diff --git a/packages/circuit-ui/components/Popover/__snapshots__/Popover.spec.tsx.snap b/packages/circuit-ui/components/Popover/__snapshots__/Popover.spec.tsx.snap new file mode 100644 index 0000000000..b76a1918ad --- /dev/null +++ b/packages/circuit-ui/components/Popover/__snapshots__/Popover.spec.tsx.snap @@ -0,0 +1,685 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Popover styles should render popover on auto 1`] = ` +HTMLCollection [ + , + @media (max-width:479px) { + .circuit-0 { + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; + background-color: rgba(0,0,0,0.4); + pointer-events: none; + } +} + +
, + .circuit-1 { + background-color: #FFF; + padding: 12px 32px 12px 16px; + border: 0; + color: #1A1A1A; + -webkit-text-decoration: none; + text-decoration: none; + position: relative; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: start; + -webkit-justify-content: flex-start; + -ms-flex-pack: start; + justify-content: flex-start; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + width: 100%; + font-size: 16px; + line-height: 24px; +} + +.circuit-1:hover { + background-color: #F5F5F5; + cursor: pointer; +} + +.circuit-1:focus { + outline: 0; + box-shadow: inset 0 0 0 4px #AFD0FE; + z-index: 1; +} + +.circuit-1:focus::-moz-focus-inner { + border: 0; +} + +.circuit-1:active { + background-color: #E6E6E6; +} + +.circuit-0 { + margin-right: 8px; +} + +.circuit-2 { + padding: 8px 0px; + border: 1px solid #E6E6E6; + box-sizing: border-box; + border-radius: 8px; + background-color: #FFF; + box-shadow: 0 3px 8px 0 rgba(0,0,0,0.2); +} + +@media (max-width:479px) { + .circuit-2 { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; + } +} + +
+ +
, +] +`; + +exports[`Popover styles should render popover on bottom 1`] = ` +HTMLCollection [ + , + @media (max-width:479px) { + .circuit-0 { + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; + background-color: rgba(0,0,0,0.4); + pointer-events: none; + } +} + +
, + .circuit-1 { + background-color: #FFF; + padding: 12px 32px 12px 16px; + border: 0; + color: #1A1A1A; + -webkit-text-decoration: none; + text-decoration: none; + position: relative; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: start; + -webkit-justify-content: flex-start; + -ms-flex-pack: start; + justify-content: flex-start; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + width: 100%; + font-size: 16px; + line-height: 24px; +} + +.circuit-1:hover { + background-color: #F5F5F5; + cursor: pointer; +} + +.circuit-1:focus { + outline: 0; + box-shadow: inset 0 0 0 4px #AFD0FE; + z-index: 1; +} + +.circuit-1:focus::-moz-focus-inner { + border: 0; +} + +.circuit-1:active { + background-color: #E6E6E6; +} + +.circuit-0 { + margin-right: 8px; +} + +.circuit-2 { + padding: 8px 0px; + border: 1px solid #E6E6E6; + box-sizing: border-box; + border-radius: 8px; + background-color: #FFF; + box-shadow: 0 3px 8px 0 rgba(0,0,0,0.2); +} + +@media (max-width:479px) { + .circuit-2 { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; + } +} + +
+ +
, +] +`; + +exports[`Popover styles should render popover on left 1`] = ` +HTMLCollection [ + , + @media (max-width:479px) { + .circuit-0 { + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; + background-color: rgba(0,0,0,0.4); + pointer-events: none; + } +} + +
, + .circuit-1 { + background-color: #FFF; + padding: 12px 32px 12px 16px; + border: 0; + color: #1A1A1A; + -webkit-text-decoration: none; + text-decoration: none; + position: relative; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: start; + -webkit-justify-content: flex-start; + -ms-flex-pack: start; + justify-content: flex-start; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + width: 100%; + font-size: 16px; + line-height: 24px; +} + +.circuit-1:hover { + background-color: #F5F5F5; + cursor: pointer; +} + +.circuit-1:focus { + outline: 0; + box-shadow: inset 0 0 0 4px #AFD0FE; + z-index: 1; +} + +.circuit-1:focus::-moz-focus-inner { + border: 0; +} + +.circuit-1:active { + background-color: #E6E6E6; +} + +.circuit-0 { + margin-right: 8px; +} + +.circuit-2 { + padding: 8px 0px; + border: 1px solid #E6E6E6; + box-sizing: border-box; + border-radius: 8px; + background-color: #FFF; + box-shadow: 0 3px 8px 0 rgba(0,0,0,0.2); +} + +@media (max-width:479px) { + .circuit-2 { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; + } +} + +
+ +
, +] +`; + +exports[`Popover styles should render popover on right 1`] = ` +HTMLCollection [ + , + @media (max-width:479px) { + .circuit-0 { + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; + background-color: rgba(0,0,0,0.4); + pointer-events: none; + } +} + +
, + .circuit-1 { + background-color: #FFF; + padding: 12px 32px 12px 16px; + border: 0; + color: #1A1A1A; + -webkit-text-decoration: none; + text-decoration: none; + position: relative; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: start; + -webkit-justify-content: flex-start; + -ms-flex-pack: start; + justify-content: flex-start; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + width: 100%; + font-size: 16px; + line-height: 24px; +} + +.circuit-1:hover { + background-color: #F5F5F5; + cursor: pointer; +} + +.circuit-1:focus { + outline: 0; + box-shadow: inset 0 0 0 4px #AFD0FE; + z-index: 1; +} + +.circuit-1:focus::-moz-focus-inner { + border: 0; +} + +.circuit-1:active { + background-color: #E6E6E6; +} + +.circuit-0 { + margin-right: 8px; +} + +.circuit-2 { + padding: 8px 0px; + border: 1px solid #E6E6E6; + box-sizing: border-box; + border-radius: 8px; + background-color: #FFF; + box-shadow: 0 3px 8px 0 rgba(0,0,0,0.2); +} + +@media (max-width:479px) { + .circuit-2 { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; + } +} + +
+ +
, +] +`; + +exports[`Popover styles should render popover on top 1`] = ` +HTMLCollection [ + , + @media (max-width:479px) { + .circuit-0 { + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; + background-color: rgba(0,0,0,0.4); + pointer-events: none; + } +} + +
, + .circuit-1 { + background-color: #FFF; + padding: 12px 32px 12px 16px; + border: 0; + color: #1A1A1A; + -webkit-text-decoration: none; + text-decoration: none; + position: relative; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: start; + -webkit-justify-content: flex-start; + -ms-flex-pack: start; + justify-content: flex-start; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + width: 100%; + font-size: 16px; + line-height: 24px; +} + +.circuit-1:hover { + background-color: #F5F5F5; + cursor: pointer; +} + +.circuit-1:focus { + outline: 0; + box-shadow: inset 0 0 0 4px #AFD0FE; + z-index: 1; +} + +.circuit-1:focus::-moz-focus-inner { + border: 0; +} + +.circuit-1:active { + background-color: #E6E6E6; +} + +.circuit-0 { + margin-right: 8px; +} + +.circuit-2 { + padding: 8px 0px; + border: 1px solid #E6E6E6; + box-sizing: border-box; + border-radius: 8px; + background-color: #FFF; + box-shadow: 0 3px 8px 0 rgba(0,0,0,0.2); +} + +@media (max-width:479px) { + .circuit-2 { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; + } +} + +
+ +
, +] +`; + +exports[`Popover styles should render with default styles 1`] = ` +HTMLCollection [ + , + @media (max-width:479px) { + .circuit-0 { + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; + background-color: rgba(0,0,0,0.4); + pointer-events: none; + } +} + +
, + .circuit-1 { + background-color: #FFF; + padding: 12px 32px 12px 16px; + border: 0; + color: #1A1A1A; + -webkit-text-decoration: none; + text-decoration: none; + position: relative; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: start; + -webkit-justify-content: flex-start; + -ms-flex-pack: start; + justify-content: flex-start; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + width: 100%; + font-size: 16px; + line-height: 24px; +} + +.circuit-1:hover { + background-color: #F5F5F5; + cursor: pointer; +} + +.circuit-1:focus { + outline: 0; + box-shadow: inset 0 0 0 4px #AFD0FE; + z-index: 1; +} + +.circuit-1:focus::-moz-focus-inner { + border: 0; +} + +.circuit-1:active { + background-color: #E6E6E6; +} + +.circuit-0 { + margin-right: 8px; +} + +.circuit-2 { + padding: 8px 0px; + border: 1px solid #E6E6E6; + box-sizing: border-box; + border-radius: 8px; + background-color: #FFF; + box-shadow: 0 3px 8px 0 rgba(0,0,0,0.2); +} + +@media (max-width:479px) { + .circuit-2 { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; + } +} + +
+ +
, +] +`; diff --git a/packages/circuit-ui/components/Popover/index.js b/packages/circuit-ui/components/Popover/index.js deleted file mode 100644 index 1b804ada8d..0000000000 --- a/packages/circuit-ui/components/Popover/index.js +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Copyright 2019, SumUp Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import Popover from './Popover'; - -export default Popover; diff --git a/packages/circuit-ui/components/Popover/index.tsx b/packages/circuit-ui/components/Popover/index.tsx new file mode 100644 index 0000000000..8e95e5779d --- /dev/null +++ b/packages/circuit-ui/components/Popover/index.tsx @@ -0,0 +1,33 @@ +/** + * Copyright 2021, SumUp Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Copyright 2021, SumUp Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Popover } from './Popover'; + +export default Popover; diff --git a/packages/circuit-ui/jest.setup.js b/packages/circuit-ui/jest.setup.js index bd09bed28e..b1416a55e8 100644 --- a/packages/circuit-ui/jest.setup.js +++ b/packages/circuit-ui/jest.setup.js @@ -59,3 +59,20 @@ expect.addSnapshotSerializer( }, }), ); + +global.matchMedia = jest.fn().mockImplementation((query) => ({ + matches: false, + media: query, + onchange: null, + /** + * @deprecated + */ + addListener: jest.fn(), + /** + * @deprecated + */ + removeListener: jest.fn(), + addEventListener: jest.fn(), + removeEventListener: jest.fn(), + dispatchEvent: jest.fn(), +})); diff --git a/packages/circuit-ui/package.json b/packages/circuit-ui/package.json index dfa64ecf66..242352218d 100644 --- a/packages/circuit-ui/package.json +++ b/packages/circuit-ui/package.json @@ -36,6 +36,7 @@ "static-styles": "cross-env BABEL_ENV=static babel-node --extensions '.js,.ts,.tsx' ./scripts/static-styles/cli.js" }, "dependencies": { + "@popperjs/core": "^2.9.2", "cross-spawn": "^7.0.3", "jscodeshift": "^0.12.0", "lodash": "^4.17.11", @@ -45,7 +46,8 @@ "react-dates": "^21.2.0", "react-modal": "^3.8.1", "react-number-format": "^4.4.1", - "react-popper": "^1.3.3", + "react-popper": "^2.2.5", + "react-use": "^17.2.4", "tiny-warning": "^1.0.3", "yargs": "^17.0.1" }, diff --git a/packages/circuit-ui/styles/style-mixins.ts b/packages/circuit-ui/styles/style-mixins.ts index 70366114d6..de1268df2a 100644 --- a/packages/circuit-ui/styles/style-mixins.ts +++ b/packages/circuit-ui/styles/style-mixins.ts @@ -314,7 +314,6 @@ export const inputOutline = ( focus: theme.colors.p500, active: theme.colors.p500, }; - break; } } @@ -334,3 +333,44 @@ export const inputOutline = ( } `; }; + +/** + * Visually communicates that the listItem (eg. Popover or Dropdown component) is hovered, active or focused. + */ +export const listItem = ( + args: + | Theme + | { + theme: Theme; + destructive?: boolean; + }, +): SerializedStyles => { + const theme = getTheme(args); + const options = isTheme(args) ? { destructive: false } : args; + + return css` + background-color: ${theme.colors.white}; + padding: ${theme.spacings.kilo} ${theme.spacings.tera} + ${theme.spacings.kilo} ${theme.spacings.mega}; + border: 0; + color: ${options.destructive + ? theme.colors.danger + : theme.colors.bodyColor}; + text-decoration: none; + position: relative; + + &:hover { + background-color: ${theme.colors.n100}; + cursor: pointer; + } + + &:focus { + ${focusOutline('inset')({ theme })}; + z-index: ${theme.zIndex.absolute}; + } + + &:active { + background-color: ${theme.colors.n200}; + } + `; +}; diff --git a/yarn.lock b/yarn.lock index 528cce7b63..ff6a3d4091 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1215,13 +1215,20 @@ core-js-pure "^3.0.0" regenerator-runtime "^0.13.4" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.4", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": +"@babel/runtime@^7.0.0", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.4", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": version "7.13.10" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.13.10.tgz#47d42a57b6095f4468da440388fdbad8bebf0d7d" integrity sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw== dependencies: regenerator-runtime "^0.13.4" +"@babel/runtime@^7.1.2": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.0.tgz#46794bc20b612c5f75e62dd071e24dfd95f1cbe6" + integrity sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA== + dependencies: + regenerator-runtime "^0.13.4" + "@babel/template@^7.12.13", "@babel/template@^7.12.7", "@babel/template@^7.3.3": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.13.tgz#530265be8a2589dbb37523844c5bcb55947fb327" @@ -1629,14 +1636,6 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" -"@hypnosphi/create-react-context@^0.3.1": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@hypnosphi/create-react-context/-/create-react-context-0.3.1.tgz#f8bfebdc7665f5d426cba3753e0e9c7d3154d7c6" - integrity sha512-V1klUed202XahrWJLLOT3EXNeCpFHCcJntdFGI15ntCwau+jfT386w7OFTMaCqOgXUH1fa0w/I1oZs+i/Rfr0A== - dependencies: - gud "^1.0.0" - warning "^4.0.3" - "@icons/material@^0.2.4": version "0.2.4" resolved "https://registry.yarnpkg.com/@icons/material/-/material-0.2.4.tgz#e90c9f71768b3736e76d7dd6783fc6c2afa88bc8" @@ -3003,7 +3002,7 @@ schema-utils "^2.6.5" source-map "^0.7.3" -"@popperjs/core@^2.5.4", "@popperjs/core@^2.6.0": +"@popperjs/core@^2.5.4", "@popperjs/core@^2.6.0", "@popperjs/core@^2.9.2": version "2.9.2" resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.9.2.tgz#adea7b6953cbb34651766b0548468e743c6a2353" integrity sha512-VZMYa7+fXHdwIq1TDhSXoVmSPEGM/aa+6Aiq3nVVJ9bXr24zScr+NlKFKC3iPljA7ho/GAZr+d2jOf5GIRC30Q== @@ -4326,6 +4325,11 @@ resolved "https://registry.yarnpkg.com/@types/jest/-/jest-23.3.14.tgz#37daaf78069e7948520474c87b80092ea912520a" integrity sha512-Q5hTcfdudEL2yOmluA1zaSyPbzWPmJ3XfSWeP3RyoYvS9hnje1ZyagrZOuQ6+1nQC1Gw+7gap3pLNL3xL6UBug== +"@types/js-cookie@^2.2.6": + version "2.2.6" + resolved "https://registry.yarnpkg.com/@types/js-cookie/-/js-cookie-2.2.6.tgz#f1a1cb35aff47bc5cfb05cb0c441ca91e914c26f" + integrity sha512-+oY0FDTO2GYKEV0YPvSshGq9t7YozVkgvXLty7zogQNuCxBhT9/3INX9Q7H1aRZ4SUDRXAKlJuA4EA5nTt7SNw== + "@types/jscodeshift@^0.11.0": version "0.11.0" resolved "https://registry.yarnpkg.com/@types/jscodeshift/-/jscodeshift-0.11.0.tgz#7224cf1a4d0383b4fb2694ffed52f57b45c3325b" @@ -4871,6 +4875,11 @@ "@webassemblyjs/wast-parser" "1.9.0" "@xtuc/long" "4.2.2" +"@xobotyi/scrollbar-width@^1.9.5": + version "1.9.5" + resolved "https://registry.yarnpkg.com/@xobotyi/scrollbar-width/-/scrollbar-width-1.9.5.tgz#80224a6919272f405b87913ca13b92929bdf3c4d" + integrity sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ== + "@xstate/react@1.0.0-rc.3": version "1.0.0-rc.3" resolved "https://registry.yarnpkg.com/@xstate/react/-/react-1.0.0-rc.3.tgz#a5974c651849604636fd9ed4a371f8fac538b8d6" @@ -7299,6 +7308,14 @@ css-color-keywords@^1.0.0: resolved "https://registry.yarnpkg.com/css-color-keywords/-/css-color-keywords-1.0.0.tgz#fea2616dc676b2962686b3af8dbdbe180b244e05" integrity sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU= +css-in-js-utils@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/css-in-js-utils/-/css-in-js-utils-2.0.1.tgz#3b472b398787291b47cfe3e44fecfdd9e914ba99" + integrity sha512-PJF0SpJT+WdbVVt0AOYp9C8GnuruRlL/UFW7932nLWmFLQTaWEzTBQEx7/hn4BuV+WON75iAViSUJLiU3PKbpA== + dependencies: + hyphenate-style-name "^1.0.2" + isobject "^3.0.1" + css-loader@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-3.6.0.tgz#2e4b2c7e6e2d27f8c8f28f61bffcd2e6c91ef645" @@ -7458,6 +7475,11 @@ csstype@^3.0.2: resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.7.tgz#2a5fb75e1015e84dd15692f71e89a1450290950b" integrity sha512-KxnUB0ZMlnUWCsx2Z8MUsr6qV6ja1w9ArPErJaJaF8a5SOWoHLIszeCTKGRGRgtLgYrs1E8CHkNSP1VZTTPc9g== +csstype@^3.0.6: + version "3.0.8" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.8.tgz#d2266a792729fb227cd216fb572f43728e1ad340" + integrity sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw== + csv-generate@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/csv-generate/-/csv-generate-3.3.0.tgz#0e25658f1bb9806d94fec7b270896a35c7eedf1a" @@ -7603,18 +7625,6 @@ dedent@^0.7.0: resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= -deep-equal@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" - integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== - dependencies: - is-arguments "^1.0.4" - is-date-object "^1.0.1" - is-regex "^1.0.4" - object-is "^1.0.1" - object-keys "^1.1.1" - regexp.prototype.flags "^1.2.0" - deep-extend@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" @@ -9011,11 +9021,21 @@ fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= +fast-shallow-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fast-shallow-equal/-/fast-shallow-equal-1.0.0.tgz#d4dcaf6472440dcefa6f88b98e3251e27f25628b" + integrity sha512-HPtaa38cPgWvaCFmRNhlc6NG7pv6NUHqjPgVAkWGoB9mQMwYB27/K0CvOM5Czy+qpT3e8XJ6Q4aPAnzpNpzNaw== + fast-xml-parser@^3.12.17: version "3.16.0" resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-3.16.0.tgz#d905e7e6b28fc4648cabebcb074363867fb56ee2" integrity sha512-U+bpScacfgnfNfIKlWHDu4u6rtOaCyxhblOLJ8sZPkhsjgGqdZmVPBhdOyvdMGCDt8CsAv+cssOP3NzQptNt2w== +fastest-stable-stringify@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/fastest-stable-stringify/-/fastest-stable-stringify-2.0.2.tgz#3757a6774f6ec8de40c4e86ec28ea02417214c76" + integrity sha512-bijHueCGd0LqqNK9b5oCMHc0MluJAx0cwqASgbWMvkO01lCYgIhacVRLcaDz3QnyYIRNJRDwMb41VuT6pHJ91Q== + fastq@^1.6.0: version "1.11.0" resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.11.0.tgz#bb9fb955a07130a918eb63c1f5161cc32a5d0858" @@ -10339,6 +10359,11 @@ husky@^4.0.0: slash "^3.0.0" which-pm-runs "^1.0.0" +hyphenate-style-name@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz#691879af8e220aea5750e8827db4ef62a54e361d" + integrity sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ== + iconv-lite@0.4.24, iconv-lite@^0.4.17, iconv-lite@^0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -10504,6 +10529,13 @@ inline-style-parser@0.1.1: resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.1.1.tgz#ec8a3b429274e9c0a1f1c4ffa9453a7fef72cea1" integrity sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q== +inline-style-prefixer@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/inline-style-prefixer/-/inline-style-prefixer-6.0.0.tgz#f73d5dbf2855733d6b153a4d24b7b47a73e9770b" + integrity sha512-XTHvRUS4ZJNzC1GixJRmOlWSS45fSt+DJoyQC9ytj0WxQfcgofQtDtyKKYxHUqEsWCs+LIWftPF1ie7+i012Fg== + dependencies: + css-in-js-utils "^2.0.0" + inquirer@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9" @@ -10642,7 +10674,7 @@ is-alphanumerical@^1.0.0: is-alphabetical "^1.0.0" is-decimal "^1.0.0" -is-arguments@^1.0.4, is-arguments@^1.1.0: +is-arguments@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.0.tgz#62353031dfbee07ceb34656a6bde59efecae8dd9" integrity sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg== @@ -11738,6 +11770,11 @@ jest@^26.6.3: import-local "^3.0.2" jest-cli "^26.6.3" +js-cookie@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-2.2.1.tgz#69e106dc5d5806894562902aa5baec3744e9b2b8" + integrity sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ== + js-string-escape@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/js-string-escape/-/js-string-escape-1.0.1.tgz#e2625badbc0d67c7533e9edc1068c587ae4137ef" @@ -13294,6 +13331,20 @@ nan@^2.12.1: resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19" integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ== +nano-css@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/nano-css/-/nano-css-5.3.1.tgz#b709383e07ad3be61f64edffacb9d98250b87a1f" + integrity sha512-ENPIyNzANQRyYVvb62ajDd7PAyIgS2LIUnT9ewih4yrXSZX4hKoUwssy8WjUH++kEOA5wUTMgNnV7ko5n34kUA== + dependencies: + css-tree "^1.1.2" + csstype "^3.0.6" + fastest-stable-stringify "^2.0.2" + inline-style-prefixer "^6.0.0" + rtl-css-js "^1.14.0" + sourcemap-codec "^1.4.8" + stacktrace-js "^2.0.2" + stylis "^4.0.6" + nanoid@^3.1.23: version "3.1.23" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.23.tgz#f744086ce7c2bc47ee0a8472574d5c78e4183a81" @@ -14695,11 +14746,6 @@ polished@^4.0.5: dependencies: "@babel/runtime" "^7.12.5" -popper.js@^1.14.4: - version "1.16.1" - resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b" - integrity sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ== - posix-character-classes@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" @@ -15461,20 +15507,7 @@ react-popper-tooltip@^3.1.1: "@popperjs/core" "^2.5.4" react-popper "^2.2.4" -react-popper@^1.3.3: - version "1.3.11" - resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-1.3.11.tgz#a2cc3f0a67b75b66cfa62d2c409f9dd1fcc71ffd" - integrity sha512-VSA/bS+pSndSF2fiasHK/PTEEAyOpX60+H5EPAjoArr8JGm+oihu4UbrqcEBpQibJxBVCpYyjAX7abJ+7DoYVg== - dependencies: - "@babel/runtime" "^7.1.2" - "@hypnosphi/create-react-context" "^0.3.1" - deep-equal "^1.1.1" - popper.js "^1.14.4" - prop-types "^15.6.1" - typed-styles "^0.0.7" - warning "^4.0.2" - -react-popper@^2.2.4: +react-popper@^2.2.4, react-popper@^2.2.5: version "2.2.5" resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-2.2.5.tgz#1214ef3cec86330a171671a4fbcbeeb65ee58e96" integrity sha512-kxGkS80eQGtLl18+uig1UIf9MKixFSyPxglsgLBxlYnyDf65BiY9B3nZSc6C9XUNDgStROB0fMQlTEz1KxGddw== @@ -15550,6 +15583,31 @@ react-textarea-autosize@^8.1.1, react-textarea-autosize@^8.3.0: use-composed-ref "^1.0.0" use-latest "^1.0.0" +react-universal-interface@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/react-universal-interface/-/react-universal-interface-0.6.2.tgz#5e8d438a01729a4dbbcbeeceb0b86be146fe2b3b" + integrity sha512-dg8yXdcQmvgR13RIlZbTRQOoUrDciFVoSBZILwjE2LFISxZZ8loVJKAkuzswl5js8BHda79bIb2b84ehU8IjXw== + +react-use@^17.2.4: + version "17.2.4" + resolved "https://registry.yarnpkg.com/react-use/-/react-use-17.2.4.tgz#1f89be3db0a8237c79253db0a15e12bbe3cfeff1" + integrity sha512-vQGpsAM0F5UIlshw5UI8ULGPS4yn5rm7/qvn3T1Gnkrz7YRMEEMh+ynKcmRloOyiIeLvKWiQjMiwRGtdbgs5qQ== + dependencies: + "@types/js-cookie" "^2.2.6" + "@xobotyi/scrollbar-width" "^1.9.5" + copy-to-clipboard "^3.3.1" + fast-deep-equal "^3.1.3" + fast-shallow-equal "^1.0.0" + js-cookie "^2.2.1" + nano-css "^5.3.1" + react-universal-interface "^0.6.2" + resize-observer-polyfill "^1.5.1" + screenfull "^5.1.0" + set-harmonic-interval "^1.0.1" + throttle-debounce "^3.0.1" + ts-easing "^0.2.0" + tslib "^2.1.0" + react-with-direction@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/react-with-direction/-/react-with-direction-1.3.1.tgz#9fd414564f0ffe6947e5ff176f6132dd83f8b8df" @@ -15897,7 +15955,7 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" -regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.3.1: +regexp.prototype.flags@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26" integrity sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA== @@ -16114,6 +16172,11 @@ reselect@^4.0.0: resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.0.0.tgz#f2529830e5d3d0e021408b246a206ef4ea4437f7" integrity sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA== +resize-observer-polyfill@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464" + integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg== + resolve-cwd@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" @@ -16225,6 +16288,13 @@ rsvp@^4.8.4: resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" integrity sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA== +rtl-css-js@^1.14.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/rtl-css-js/-/rtl-css-js-1.14.1.tgz#f79781d6a0c510abe73fde60aa3cbe9dfd134a45" + integrity sha512-G9N1s/6329FpJr8k9e1U/Lg0IDWThv99sb7k0IrXHjSnubxe01h52/ajsPRafJK1/2Vqrhz3VKLe3E1dx6jS9Q== + dependencies: + "@babel/runtime" "^7.1.2" + run-async@^2.2.0, run-async@^2.4.0: version "2.4.1" resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" @@ -16368,6 +16438,11 @@ schema-utils@^3.0.0: ajv "^6.12.5" ajv-keywords "^3.5.2" +screenfull@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/screenfull/-/screenfull-5.1.0.tgz#85c13c70f4ead4c1b8a935c70010dfdcd2c0e5c8" + integrity sha512-dYaNuOdzr+kc6J6CFcBrzkLCfyGcMg+gWkJ8us93IQ7y1cevhQAugFsaCdMHb6lw8KV3xPzSxzH7zM1dQap9mA== + select@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d" @@ -16506,6 +16581,11 @@ set-blocking@^2.0.0, set-blocking@~2.0.0: resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= +set-harmonic-interval@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/set-harmonic-interval/-/set-harmonic-interval-1.0.1.tgz#e1773705539cdfb80ce1c3d99e7f298bb3995249" + integrity sha512-AhICkFV84tBP1aWqPwLZqFvAwqEoVA9kxNMniGEUvzOlm4vLmOFLiTT3UZ6bziJTy4bOVpzWGTfSCbmaayGx8g== + set-value@^2.0.0, set-value@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" @@ -16781,6 +16861,11 @@ source-map-url@^0.4.0: resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== +source-map@0.5.6: + version "0.5.6" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" + integrity sha1-dc449SvwczxafwwRjYEzSiu19BI= + source-map@^0.5.0, source-map@^0.5.6, source-map@^0.5.7: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" @@ -16796,6 +16881,11 @@ source-map@^0.7.3: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== +sourcemap-codec@^1.4.8: + version "1.4.8" + resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" + integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== + space-separated-tokens@^1.0.0: version "1.1.5" resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz#85f32c3d10d9682007e917414ddc5c26d1aa6899" @@ -16940,6 +17030,13 @@ stable@^0.1.8: resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== +stack-generator@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/stack-generator/-/stack-generator-2.0.5.tgz#fb00e5b4ee97de603e0773ea78ce944d81596c36" + integrity sha512-/t1ebrbHkrLrDuNMdeAcsvynWgoH/i4o8EGGfX7dEYDoTXOYVAkEpFdtshlvabzc6JlJ8Kf9YdFEoz7JkzGN9Q== + dependencies: + stackframe "^1.1.1" + stack-utils@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.4.tgz#4b600971dcfc6aed0cbdf2a8268177cc916c87c8" @@ -16959,6 +17056,23 @@ stackframe@^1.1.1: resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.2.0.tgz#52429492d63c62eb989804c11552e3d22e779303" integrity sha512-GrdeshiRmS1YLMYgzF16olf2jJ/IzxXY9lhKOskuVziubpTYcYqyOwYeJKzQkwy7uN0fYSsbsC4RQaXf9LCrYA== +stacktrace-gps@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/stacktrace-gps/-/stacktrace-gps-3.0.4.tgz#7688dc2fc09ffb3a13165ebe0dbcaf41bcf0c69a" + integrity sha512-qIr8x41yZVSldqdqe6jciXEaSCKw1U8XTXpjDuy0ki/apyTn/r3w9hDAAQOhZdxvsC93H+WwwEu5cq5VemzYeg== + dependencies: + source-map "0.5.6" + stackframe "^1.1.1" + +stacktrace-js@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/stacktrace-js/-/stacktrace-js-2.0.2.tgz#4ca93ea9f494752d55709a081d400fdaebee897b" + integrity sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg== + dependencies: + error-stack-parser "^2.0.6" + stack-generator "^2.0.5" + stacktrace-gps "^3.0.4" + state-toggle@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/state-toggle/-/state-toggle-1.0.3.tgz#e123b16a88e143139b09c6852221bc9815917dfe" @@ -17316,6 +17430,11 @@ styled-components@^5.1.1: shallowequal "^1.1.0" supports-color "^5.5.0" +stylis@^4.0.6: + version "4.0.10" + resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.0.10.tgz#446512d1097197ab3f02fb3c258358c3f7a14240" + integrity sha512-m3k+dk7QeJw660eIKRRn3xPF6uuvHs/FFzjX3HQ5ove0qYsiygoAhwn5a3IYKaZPo5LrYD0rfVmtv1gNY1uYwg== + supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" @@ -17848,6 +17967,11 @@ ts-dedent@^2.0.0: resolved "https://registry.yarnpkg.com/ts-dedent/-/ts-dedent-2.1.1.tgz#6dd56870bb5493895171334fa5d7e929107e5bbc" integrity sha512-riHuwnzAUCfdIeTBNUq7+Yj+ANnrMXo/7+Z74dIdudS7ys2k8aSGMzpJRMFDF7CLwUTbtvi1ZZff/Wl+XxmqIA== +ts-easing@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/ts-easing/-/ts-easing-0.2.0.tgz#c8a8a35025105566588d87dbda05dd7fbfa5a4ec" + integrity sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ== + ts-essentials@^2.0.3: version "2.0.12" resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-2.0.12.tgz#c9303f3d74f75fa7528c3d49b80e089ab09d8745" @@ -17938,7 +18062,7 @@ tslib@^1.8.1, tslib@^1.9.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.0.0, tslib@^2.0.3: +tslib@^2.0.0, tslib@^2.0.3, tslib@^2.1.0: version "2.2.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.2.0.tgz#fb2c475977e35e241311ede2693cee1ec6698f5c" integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w== @@ -18061,11 +18185,6 @@ type-is@~1.6.17, type-is@~1.6.18: media-typer "0.3.0" mime-types "~2.1.24" -typed-styles@^0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/typed-styles/-/typed-styles-0.0.7.tgz#93392a008794c4595119ff62dde6809dbc40a3d9" - integrity sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q== - typedarray-to-buffer@^3.1.5: version "3.1.5" resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080"