diff --git a/src/core/Popover/Popover.test.tsx b/src/core/Popover/Popover.test.tsx index b155c8b45..139d603c3 100644 --- a/src/core/Popover/Popover.test.tsx +++ b/src/core/Popover/Popover.test.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { render, screen } from '@testing-library/react'; +import { fireEvent, render, screen } from '@testing-library/react'; import '@testing-library/jest-dom'; import { Popover } from './Popover'; @@ -70,4 +70,27 @@ describe('Component: Popover', () => { expect(container).toMatchSnapshot(); }); }); + + describe('events', () => { + it('should call onClick when tag is clicked', () => { + const onClickSpy = jest.fn(); + render( + Click this} tag="button"> + Popover content + + ); + fireEvent.click(screen.getByText('Click this')); + expect(onClickSpy).toBeCalledTimes(1); + }); + + it('should open on click when openOnClick is true', () => { + render( + Click this} tag="button"> + Popover content + + ); + fireEvent.click(screen.getByText('Click this')); + expect(screen.queryByText('Popover content')).toBeInTheDocument(); + }); + }); }); diff --git a/src/core/Popover/Popover.tsx b/src/core/Popover/Popover.tsx index 99dce9ae9..987900f25 100644 --- a/src/core/Popover/Popover.tsx +++ b/src/core/Popover/Popover.tsx @@ -1,4 +1,4 @@ -import React, { CSSProperties } from 'react'; +import React, { CSSProperties, useEffect, useState } from 'react'; import Tippy from '@tippyjs/react'; import { TippyPlacement } from '../types'; @@ -12,6 +12,19 @@ type Props = { */ isOpen?: boolean; + /** + * Optionally whether the popover should open on click instead of hover. + */ + openOnClick?: boolean; + + /** + * Optional callback that gets triggered when the tag is clicked. + * When openOnClick is true, this component will take care of its visibility + * state, unless onClick is defined. + * This should be used when wanting to take complete control over the popover. + */ + onClick?: () => void; + /** * Optionally callback that gets triggered when clicked outside the popover. * Is useful for when wanting to take complete control over the popover. @@ -83,15 +96,31 @@ export function Popover({ tag = 'span', className, isOpen, + openOnClick, + onClick, onClickOutside, style, maxWidth }: Props) { const Tag = tag; + const [visible, setVisible] = useState(openOnClick ? !!isOpen : undefined); + + useEffect(() => { + setVisible(openOnClick ? !!isOpen : undefined); + }, [openOnClick, isOpen]); + + function tagClicked() { + if (onClick) { + onClick(); + } else if (openOnClick) { + setVisible(!visible); + } + } + return ( - + {target} diff --git a/src/core/Popover/__snapshots__/Popover.test.tsx.snap b/src/core/Popover/__snapshots__/Popover.test.tsx.snap index 8e28e62e6..403899953 100644 --- a/src/core/Popover/__snapshots__/Popover.test.tsx.snap +++ b/src/core/Popover/__snapshots__/Popover.test.tsx.snap @@ -17,7 +17,7 @@ exports[`Component: Popover ui default 1`] = ` exports[`Component: Popover ui open 1`] = `
@@ -25,44 +25,13 @@ exports[`Component: Popover ui open 1`] = ` The popover should be wrapped around this div, in a span
-
-
`; exports[`Component: Popover ui with optional properties 1`] = `
-
-
`;