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`] = `
`;