Skip to content

Conversation

britt6612
Copy link
Collaborator

What does this PR do?

This PR adds an event listener to the tooltip so that when a user clicks escape the tooltip will close

Where should the reviewer start?

tip.js

What testing has been done on this PR?

storybook

How should this be manually tested?

open storybook of any of the tip stories and open in a new window then hover over tip and press escape

Do Jest tests follow these best practices?

  • screen is used for querying.
  • The correct query is used. (Refer to this list of queries)
  • asFragment() is used for snapshot testing.

Any background context you want to provide?

Tip is currently not passing these WCAG points for WCAG 1.4.13:

Dismissible
A mechanism is available to dismiss the additional content without moving pointer hover or keyboard focus, unless the additional content communicates an input error or does not obscure or replace other content;

What are the relevant issues?

Part 1 of #7552

Screenshots (if appropriate)

Do the grommet docs need to be updated?

no

Should this PR be mentioned in the release notes?

yes

Is this change backwards compatible or is it a breaking change?

backwards compatible

@britt6612 britt6612 requested review from jcfilben and taysea April 1, 2025 14:47
Copy link
Collaborator

@jcfilben jcfilben left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the tip/simple story when I hover onto the tooltip content and then try to press 'esc' the tip doesn't close.

If I set defaultVisible=true and then hover over the target and press 'esc' the tip doesn't close.

@jcfilben
Copy link
Collaborator

jcfilben commented Apr 1, 2025

On the tip/simple story when I hover onto the tooltip content and then try to press 'esc' the tip doesn't close.

If I set defaultVisible=true and then hover over the target and press 'esc' the tip doesn't close.

Update: confirmed these are working as expected when I open the story in a new window

@britt6612 britt6612 requested a review from MikeKingdom April 3, 2025 18:33
@@ -21,6 +21,20 @@ const Tip = forwardRef(

const componentRef = useForwardedRef(tipRef);

useEffect(() => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just occurred to me that we may want to use <Keyboard> instead like we do in Layer for onEsc and avoid the useEffect and such altogether. I was just reading something this morning about avoiding this kind of usage of useEffect

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it was originally not working with keyboard but now that I see its more not working in the storybook iframe let me try and switch out with keyboard

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just occurred to me that we may want to use <Keyboard> instead like we do in Layer for onEsc and avoid the useEffect and such altogether. I was just reading something this morning about avoiding this kind of usage of useEffect

This usage of useEffect is very typical and appropriate. The article I read was trying to advocate using this newer API instead:

import { useSyncExternalStore } from 'react';

// Simplified example for browser window size
function useWindowSize() {
  return useSyncExternalStore(
    // Subscribe function
    callback => {
      window.addEventListener('resize', callback);
      return () => window.removeEventListener('resize', callback);
    },
    // Get snapshot function
    () => ({ width: window.innerWidth, height: window.innerHeight })
  );
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aw gotcha will I just switched it out with keyboard but my test that I originally had was now failing. But if you want to test this way out and check out the code lmk I can work on the test in backround

@britt6612 britt6612 requested a review from MikeKingdom April 3, 2025 22:12
Copy link
Collaborator

@jcfilben jcfilben left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Behavior looks good, just holding off on marking as approved until jest test is ready

@britt6612
Copy link
Collaborator Author

britt6612 commented Apr 4, 2025

Here is the test I have

  test('pressing Escape key closes tooltip', async () => {
    const onEsc = jest.fn();
    render(
      <Grommet>
        <Tip content="tooltip text" defaultVisible>
          <button>Hover me</button>
        </Tip>
      </Grommet>,
    );

    expect(screen.getByText('tooltip text')).toBeInTheDocument();

    // Simulate pressing the Escape key
    fireEvent.keyDown(document, { key: 'Escape', keyCode: 27, which: 27 });

    // Ensure Escape key is pressed
    expect(onEsc).toHaveBeenCalledTimes(1);

    // await waitFor(() => {
    //   expect(screen.queryByText('tooltip text')).not.toBeInTheDocument();
    // });
  });

unfortunately though in the logs its showing Escape key is presses 0 times. Im not sure if either of you have ideas on why this wouldnt be called with the fireEvent

@britt6612 britt6612 requested a review from jcfilben April 4, 2025 05:48
@MikeKingdom
Copy link
Collaborator

unfortunately though in the logs its showing Escape key is presses 0 times. Im not sure if either of you have ideas on why this wouldnt be called with the fireEvent

I've never had much luck with certain key handlers in jest tests. I think if they are at the window level they don't really work like they do in the browser.

@MikeKingdom
Copy link
Collaborator

unfortunately though in the logs its showing Escape key is presses 0 times. Im not sure if either of you have ideas on why this wouldnt be called with the fireEvent

I've never had much luck with certain key handlers in jest tests. I think if they are at the window level they don't really work like they do in the browser.

Just a thought after testing the tip, can you try adding focus to whatever component you're rendering? Storybook only works if you put focus in the story pane somewhere

@britt6612
Copy link
Collaborator Author

britt6612 commented Apr 4, 2025

unfortunately though in the logs its showing Escape key is presses 0 times. Im not sure if either of you have ideas on why this wouldnt be called with the fireEvent

I've never had much luck with certain key handlers in jest tests. I think if they are at the window level they don't really work like they do in the browser.

Just a thought after testing the tip, can you try adding focus to whatever component you're rendering? Storybook only works if you put focus in the story pane somewhere

yes I can do that for the test. I kinda wanted to test the hover first then press escape but yes if I focus the button then press escape the test will be fine

UPDATE: Added the test where I added focus to the button then press escape @jcfilben @MikeKingdom

Copy link
Collaborator

@MikeKingdom MikeKingdom left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Just waiting on the circle ci tests

Copy link
Collaborator

@jcfilben jcfilben left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Look good!

@jcfilben jcfilben merged commit a2d957b into grommet:master Apr 4, 2025
13 of 14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants