From 26b2962b28345a146cd3a6974e6ef5d5e2822b00 Mon Sep 17 00:00:00 2001 From: Robin Wijnant Date: Sun, 17 Jan 2021 23:57:28 +0100 Subject: [PATCH] feat(tooltip): add tooltip component --- src/components/Tooltip/Tooltip.mdx | 38 ++++++++++++ src/components/Tooltip/Tooltip.module.css | 19 ++++++ src/components/Tooltip/Tooltip.test.tsx | 26 ++++++++ src/components/Tooltip/Tooltip.tsx | 72 +++++++++++++++++++++++ src/index.ts | 1 + 5 files changed, 156 insertions(+) create mode 100644 src/components/Tooltip/Tooltip.mdx create mode 100644 src/components/Tooltip/Tooltip.module.css create mode 100644 src/components/Tooltip/Tooltip.test.tsx create mode 100644 src/components/Tooltip/Tooltip.tsx diff --git a/src/components/Tooltip/Tooltip.mdx b/src/components/Tooltip/Tooltip.mdx new file mode 100644 index 00000000..7c8c8848 --- /dev/null +++ b/src/components/Tooltip/Tooltip.mdx @@ -0,0 +1,38 @@ +--- +name: Tooltip +menu: Components +route: /tooltip +--- + +import { Playground, Props } from 'docz'; +import { Tooltip, Menu, Button, Trash } from '../../index.ts'; + +# Popover + +A Popover is used to display extra information or actions in a compact way. + +## Best practices + +- Make sure the correct popover events are covered, depending on the event. (Click, hover, focus, etc...). + +## Examples + +### Basic usage + + + + + + + +### Bottom placement + + + + + + + +## API + + diff --git a/src/components/Tooltip/Tooltip.module.css b/src/components/Tooltip/Tooltip.module.css new file mode 100644 index 00000000..e5b1a01a --- /dev/null +++ b/src/components/Tooltip/Tooltip.module.css @@ -0,0 +1,19 @@ +.content { + border-radius: var(--border-radius-small); + background-color: var(--color-neutral-8); + color: var(--color-neutral-1); + padding: 8px 14px; + box-shadow: 0px 1px 5px rgba(0, 0, 0, 0.1); + z-index: 100; + transition: opacity 0.24s; + opacity: 1; +} + +.content.enter, +.content.exit { + opacity: 0; +} + +.triggerContainer { + display: inline-block; +} diff --git a/src/components/Tooltip/Tooltip.test.tsx b/src/components/Tooltip/Tooltip.test.tsx new file mode 100644 index 00000000..9af39e68 --- /dev/null +++ b/src/components/Tooltip/Tooltip.test.tsx @@ -0,0 +1,26 @@ +import React from 'react'; +import { fireEvent, render, waitFor } from '@testing-library/react'; + +import { Button } from '../../index'; +import Tooltip from './Tooltip'; + +describe('Tooltip', () => { + const component = ( + + + + ); + + test('show on hover', async () => { + const { queryByText, getByText } = render(component); + const button = getByText('Hover over me'); + + expect(queryByText('This is more info')).toBe(null); + + await waitFor(() => { + fireEvent.mouseEnter(button); + }); + + expect(queryByText('This is more info')).not.toBe(null); + }); +}); diff --git a/src/components/Tooltip/Tooltip.tsx b/src/components/Tooltip/Tooltip.tsx new file mode 100644 index 00000000..122e3d64 --- /dev/null +++ b/src/components/Tooltip/Tooltip.tsx @@ -0,0 +1,72 @@ +import React, { useRef, useState } from 'react'; +import { usePopper } from 'react-popper'; +import { CSSTransition } from 'react-transition-group'; +import { Placement } from '@popperjs/core'; +import classnames from 'classnames'; + +import styles from './Tooltip.module.css'; + +interface Props { + content?: React.ReactNode; + children?: React.ReactNode; + placement?: Placement; + className?: string; +} + +const Popover: React.FC = ({ content, children, placement = 'top', className }: Props) => { + const [isShown, setIsShown] = useState(false); + const divRef = useRef(null); + const contentRef = useRef(null); + const [arrowRef, setArrowRef] = useState(null); + const contentClassNames = classnames(styles.content, className); + + const hide = () => setIsShown(false); + const show = () => setIsShown(true); + + const { styles: popperStyles, attributes } = usePopper(divRef.current, contentRef.current, { + modifiers: [ + { + name: 'offset', + options: { + offset: [0, 10], + }, + }, + { + name: 'arrow', + options: { + element: arrowRef, + }, + }, + ], + placement, + }); + + return ( + <> +
+ {children} +
+ + +
+
+ {content} +
+ + + ); +}; + +export default Popover; diff --git a/src/index.ts b/src/index.ts index 7116284e..2d385a7d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -11,6 +11,7 @@ export { default as Table } from './components/Table/Table'; export { default as TextArea } from './components/TextArea/TextArea'; export { default as Popover } from './components/Popover/Popover'; export { default as Menu } from './components/Menu/Menu'; +export { default as Tooltip } from './components/Tooltip/Tooltip'; export { default as toaster } from './components/Toaster/Toaster'; export * from 'react-feather';