From a1b879a5b4956a742eae661e58ace3edb4b7c9b9 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sat, 18 Mar 2023 10:17:17 +0100 Subject: [PATCH] Add support for a tooltip on HighlightCard component --- src/servers/helpers/HighlightCard.tsx | 31 +++++++++++++-------- test/servers/helpers/HighlightCard.test.tsx | 20 +++++++++---- 2 files changed, 34 insertions(+), 17 deletions(-) diff --git a/src/servers/helpers/HighlightCard.tsx b/src/servers/helpers/HighlightCard.tsx index a272be9a..99e35ecc 100644 --- a/src/servers/helpers/HighlightCard.tsx +++ b/src/servers/helpers/HighlightCard.tsx @@ -1,21 +1,30 @@ import { faArrowAltCircleRight as linkIcon } from '@fortawesome/free-regular-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import type { FC, PropsWithChildren } from 'react'; +import type { FC, PropsWithChildren, ReactNode } from 'react'; import { Link } from 'react-router-dom'; -import { Card, CardText, CardTitle } from 'reactstrap'; +import { Card, CardText, CardTitle, UncontrolledTooltip } from 'reactstrap'; +import { useElementRef } from '../../utils/helpers/hooks'; import './HighlightCard.scss'; export type HighlightCardProps = PropsWithChildren<{ title: string; - link?: string | false; + link?: string; + tooltip?: ReactNode; }>; -const buildExtraProps = (link?: string | false) => (!link ? {} : { tag: Link, to: link }); +const buildExtraProps = (link?: string) => (!link ? {} : { tag: Link, to: link }); -export const HighlightCard: FC = ({ children, title, link }) => ( - - {link && } - {title} - {children} - -); +export const HighlightCard: FC = ({ children, title, link, tooltip }) => { + const ref = useElementRef(); + + return ( + <> + + {link && } + {title} + {children} + + {tooltip && {tooltip}} + + ); +}; diff --git a/test/servers/helpers/HighlightCard.test.tsx b/test/servers/helpers/HighlightCard.test.tsx index afc8f070..ec478de1 100644 --- a/test/servers/helpers/HighlightCard.test.tsx +++ b/test/servers/helpers/HighlightCard.test.tsx @@ -1,11 +1,12 @@ -import { render, screen } from '@testing-library/react'; +import { screen, waitFor } from '@testing-library/react'; import type { ReactNode } from 'react'; import { MemoryRouter } from 'react-router-dom'; import type { HighlightCardProps } from '../../../src/servers/helpers/HighlightCard'; import { HighlightCard } from '../../../src/servers/helpers/HighlightCard'; +import { renderWithEvents } from '../../__helpers__/setUpTest'; describe('', () => { - const setUp = (props: HighlightCardProps & { children?: ReactNode }) => render( + const setUp = (props: HighlightCardProps & { children?: ReactNode }) => renderWithEvents( , @@ -13,9 +14,9 @@ describe('', () => { it.each([ [undefined], - [false], + [''], ])('does not render icon when there is no link', (link) => { - setUp({ title: 'foo', link: link as undefined | false }); + setUp({ title: 'foo', link }); expect(screen.queryByRole('img', { hidden: true })).not.toBeInTheDocument(); expect(screen.queryByRole('link')).not.toBeInTheDocument(); @@ -27,7 +28,7 @@ describe('', () => { ['baz'], ])('renders provided title', (title) => { setUp({ title }); - expect(screen.getByText(title)).toHaveAttribute('class', expect.stringContaining('highlight-card__title')); + expect(screen.getByText(title)).toHaveClass('highlight-card__title'); }); it.each([ @@ -36,7 +37,7 @@ describe('', () => { ['baz'], ])('renders provided children', (children) => { setUp({ title: 'title', children }); - expect(screen.getByText(children)).toHaveAttribute('class', expect.stringContaining('card-text')); + expect(screen.getByText(children)).toHaveClass('card-text'); }); it.each([ @@ -49,4 +50,11 @@ describe('', () => { expect(screen.getByRole('img', { hidden: true })).toBeInTheDocument(); expect(screen.getByRole('link')).toHaveAttribute('href', `/${link}`); }); + + it('renders tooltip when provided', async () => { + const { user } = setUp({ title: 'title', children: 'Foo', tooltip: 'This is the tooltip' }); + + await user.hover(screen.getByText('Foo')); + await waitFor(() => expect(screen.getByText('This is the tooltip')).toBeInTheDocument()); + }); });