mirror of
https://github.com/grafana/grafana.git
synced 2025-01-10 08:03:58 -06:00
Toggletip: Add support to programmatically close it (#75846)
This commit is contained in:
parent
c869844a78
commit
586c78a636
@ -8,8 +8,9 @@ import { Toggletip } from './Toggletip';
|
||||
|
||||
describe('Toggletip', () => {
|
||||
it('should display toggletip after click on "Click me!" button', async () => {
|
||||
const onOpen = jest.fn();
|
||||
render(
|
||||
<Toggletip placement="auto" content="Tooltip text">
|
||||
<Toggletip placement="auto" content="Tooltip text" onOpen={onOpen}>
|
||||
<Button type="button" data-testid="myButton">
|
||||
Click me!
|
||||
</Button>
|
||||
@ -20,12 +21,70 @@ describe('Toggletip', () => {
|
||||
await userEvent.click(button);
|
||||
|
||||
expect(screen.getByTestId('toggletip-content')).toBeInTheDocument();
|
||||
expect(onOpen).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should display toggletip if configured as `show=true`', async () => {
|
||||
render(
|
||||
<Toggletip placement="auto" content="Tooltip text" show={true}>
|
||||
<Button type="button" data-testid="myButton">
|
||||
Click me!
|
||||
</Button>
|
||||
</Toggletip>
|
||||
);
|
||||
|
||||
expect(await screen.findByTestId('toggletip-content')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should not close if configured as `show=true`', async () => {
|
||||
const onClose = jest.fn();
|
||||
render(
|
||||
<Toggletip placement="auto" content="Tooltip text" show={true} onClose={onClose}>
|
||||
<Button type="button" data-testid="myButton">
|
||||
Click me!
|
||||
</Button>
|
||||
</Toggletip>
|
||||
);
|
||||
|
||||
expect(await screen.findByTestId('toggletip-content')).toBeInTheDocument();
|
||||
|
||||
// Close button should not close the toggletip
|
||||
const closeButton = screen.getByTestId('toggletip-header-close');
|
||||
expect(closeButton).toBeInTheDocument();
|
||||
await userEvent.click(closeButton);
|
||||
expect(onClose).toHaveBeenCalledTimes(1);
|
||||
|
||||
// Escape should not close the toggletip
|
||||
const button = screen.getByTestId('myButton');
|
||||
await userEvent.click(button);
|
||||
await userEvent.keyboard('{escape}');
|
||||
expect(onClose).toHaveBeenCalledTimes(2);
|
||||
|
||||
// Either way, the toggletip should still be visible
|
||||
expect(await screen.findByTestId('toggletip-content')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should not open if configured as `show=false`', async () => {
|
||||
const onOpen = jest.fn();
|
||||
render(
|
||||
<Toggletip placement="auto" content="Tooltip text" show={false} onOpen={onOpen}>
|
||||
<Button type="button" data-testid="myButton">
|
||||
Click me!
|
||||
</Button>
|
||||
</Toggletip>
|
||||
);
|
||||
|
||||
const button = screen.getByTestId('myButton');
|
||||
await userEvent.click(button);
|
||||
|
||||
expect(await screen.queryByTestId('toggletip-content')).not.toBeInTheDocument();
|
||||
expect(onOpen).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should close toggletip after click on close button', async () => {
|
||||
const closeSpy = jest.fn();
|
||||
const onClose = jest.fn();
|
||||
render(
|
||||
<Toggletip placement="auto" content="Tooltip text" onClose={closeSpy}>
|
||||
<Toggletip placement="auto" content="Tooltip text" onClose={onClose}>
|
||||
<Button type="button" data-testid="myButton">
|
||||
Click me!
|
||||
</Button>
|
||||
@ -40,13 +99,13 @@ describe('Toggletip', () => {
|
||||
expect(closeButton).toBeInTheDocument();
|
||||
await userEvent.click(closeButton);
|
||||
|
||||
expect(closeSpy).toHaveBeenCalledTimes(1);
|
||||
expect(onClose).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should close toggletip after press ESC', async () => {
|
||||
const closeSpy = jest.fn();
|
||||
const onClose = jest.fn();
|
||||
render(
|
||||
<Toggletip placement="auto" content="Tooltip text" onClose={closeSpy}>
|
||||
<Toggletip placement="auto" content="Tooltip text" onClose={onClose}>
|
||||
<Button type="button" data-testid="myButton">
|
||||
Click me!
|
||||
</Button>
|
||||
@ -59,13 +118,13 @@ describe('Toggletip', () => {
|
||||
|
||||
await userEvent.keyboard('{escape}');
|
||||
|
||||
expect(closeSpy).toHaveBeenCalledTimes(1);
|
||||
expect(onClose).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should display the toggletip after press ENTER', async () => {
|
||||
const closeSpy = jest.fn();
|
||||
const onOpen = jest.fn();
|
||||
render(
|
||||
<Toggletip placement="auto" content="Tooltip text" onClose={closeSpy}>
|
||||
<Toggletip placement="auto" content="Tooltip text" onOpen={onOpen}>
|
||||
<Button type="button" data-testid="myButton">
|
||||
Click me!
|
||||
</Button>
|
||||
@ -80,15 +139,16 @@ describe('Toggletip', () => {
|
||||
await userEvent.keyboard('{enter}');
|
||||
|
||||
expect(screen.getByTestId('toggletip-content')).toBeInTheDocument();
|
||||
expect(onOpen).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should be able to focus toggletip content next in DOM order - forwards and backwards', async () => {
|
||||
const closeSpy = jest.fn();
|
||||
const onClose = jest.fn();
|
||||
const afterInDom = 'Outside of toggletip';
|
||||
|
||||
render(
|
||||
<>
|
||||
<Toggletip placement="auto" content="Tooltip text" onClose={closeSpy}>
|
||||
<Toggletip placement="auto" content="Tooltip text" onClose={onClose}>
|
||||
<Button type="button" data-testid="myButton">
|
||||
Click me!
|
||||
</Button>
|
||||
@ -134,9 +194,9 @@ describe('Toggletip', () => {
|
||||
});
|
||||
|
||||
it('should restore focus to the button that opened the toggletip when closed from within the toggletip', async () => {
|
||||
const closeSpy = jest.fn();
|
||||
const onClose = jest.fn();
|
||||
render(
|
||||
<Toggletip placement="auto" content="Tooltip text" onClose={closeSpy}>
|
||||
<Toggletip placement="auto" content="Tooltip text" onClose={onClose}>
|
||||
<Button type="button" data-testid="myButton">
|
||||
Click me!
|
||||
</Button>
|
||||
@ -156,12 +216,12 @@ describe('Toggletip', () => {
|
||||
});
|
||||
|
||||
it('should NOT restore focus to the button that opened the toggletip when closed from outside the toggletip', async () => {
|
||||
const closeSpy = jest.fn();
|
||||
const onClose = jest.fn();
|
||||
const afterInDom = 'Outside of toggletip';
|
||||
|
||||
render(
|
||||
<>
|
||||
<Toggletip placement="auto" content="Tooltip text" onClose={closeSpy}>
|
||||
<Toggletip placement="auto" content="Tooltip text" onClose={onClose}>
|
||||
<Button type="button" data-testid="myButton">
|
||||
Click me!
|
||||
</Button>
|
||||
|
@ -30,6 +30,10 @@ export interface ToggletipProps {
|
||||
children: JSX.Element;
|
||||
/** Determine whether the toggletip should fit its content or not */
|
||||
fitContent?: boolean;
|
||||
/** Determine whether the toggletip should be shown or not */
|
||||
show?: boolean;
|
||||
/** Callback function to be called when the toggletip is opened */
|
||||
onOpen?: () => void;
|
||||
}
|
||||
|
||||
export const Toggletip = React.memo(
|
||||
@ -43,24 +47,31 @@ export const Toggletip = React.memo(
|
||||
onClose,
|
||||
footer,
|
||||
fitContent = false,
|
||||
onOpen,
|
||||
show,
|
||||
}: ToggletipProps) => {
|
||||
const styles = useStyles2(getStyles);
|
||||
const style = styles[theme];
|
||||
const contentRef = useRef(null);
|
||||
const [controlledVisible, setControlledVisible] = React.useState(false);
|
||||
const [controlledVisible, setControlledVisible] = React.useState(show);
|
||||
|
||||
const { getArrowProps, getTooltipProps, setTooltipRef, setTriggerRef, visible, update, tooltipRef, triggerRef } =
|
||||
usePopperTooltip(
|
||||
{
|
||||
visible: controlledVisible,
|
||||
visible: show ?? controlledVisible,
|
||||
placement: placement,
|
||||
interactive: true,
|
||||
offset: [0, 8],
|
||||
// If show is undefined, the toggletip will be shown on click
|
||||
trigger: 'click',
|
||||
onVisibleChange: (value: boolean) => {
|
||||
setControlledVisible(value);
|
||||
if (!value) {
|
||||
onVisibleChange: (visible: boolean) => {
|
||||
if (show === undefined) {
|
||||
setControlledVisible(visible);
|
||||
}
|
||||
if (!visible) {
|
||||
onClose?.();
|
||||
} else {
|
||||
onOpen?.();
|
||||
}
|
||||
},
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user