Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added useGridKeyboardNavigation #461

Merged
merged 7 commits into from
Jan 20, 2022

Conversation

laviomri
Copy link
Contributor

@laviomri laviomri commented Jan 19, 2022

Task
Added hook for using keyboard navigation in a grid-like layout. Useful for components rendering a list of items that can be navigated and selected with a keyboard.
In the future, we can add support for page up / down, home/end, tab etc...
The next PR contains a context which allows navigation between multiple sections.

(I've had the chance to sync with @MosheZemah about the implementation mid-way).

Basic

  • Used plop (npm run plop) to create a new component.
  • PR has description.
  • New component is functional and uses Hooks.
  • Component defines PropTypes.

Style

  • Styles are added to NewComponent.modules.scss file inside of the NewComponent folder. Irrelevant
  • Component uses CSS Modules. Irrelevant
  • Design is compatible with Monday Design System.

Storybook

  • Stories were added to /src/NewComponent/__stories__/NewComponent.stories.js file.
  • Stories include all flows of using the component.

Tests


const NOOP = () => {};

export default function useFullKeyboardListeners({
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I saw that we had various places that add similar key listeners, but some had slightly different key-handling. For example, treating only "Enter" as selection key, and not "Space".
If you're ok with it, I can replace some of the existing hooks to use this hook, to reduce code duplication and having a more unified behavior.

@@ -0,0 +1,106 @@
import { useCallback, useLayoutEffect, useState, useContext } from "react";
import useFullKeyboardListeners from "../useFullKeyboardListeners";
// import { GridKeyboardNavigationContext } from "../../components/GridKeyboardNavigation/GridKeyboardNavigationContext";
Copy link
Contributor Author

Choose a reason for hiding this comment

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

anything related to the context will be added in the following PR, so it's currently commented out

src/hooks/useFullKeyboardListeners.js Show resolved Hide resolved
@@ -0,0 +1,310 @@
import { NAV_DIRECTIONS } from "../../useFullKeyboardListeners";
Copy link
Contributor

Choose a reason for hiding this comment

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

A M A Z I N G!!!!

it("should set the active index to 0 when focusing for the first time", () => {
const { result } = renderHookForTest({ });

act(() => element.dispatchEvent(new Event('focus')));
Copy link
Contributor

Choose a reason for hiding this comment

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

can we use "@testing-library/user-event" for the events?.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think it's possible. the closest thing is userEvent.tab, but it's not useful here.
(the CustomEvent is also irrelevant for userEvent)

Copy link
Contributor

Choose a reason for hiding this comment

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

Don't forget that if you need real focus and not only trigger you need element.focus()
"Dispatching the event will not set the focus, that will just trigger the attached event handlers."

Copy link
Contributor Author

Choose a reason for hiding this comment

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

that's a good idea. I tried it though and the event handlers weren't triggered during the test. I suspect that this happens because of the testing environment (on the browser it works).
In any case, I only need to test the handlers, so I'm fine with it as is :)

*/

/**
* A hook which is used for accessible keyboard navigation. Useful for components rendering a list of items that can be navigated and selected with a keyboard.
Copy link
Contributor

Choose a reason for hiding this comment

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

mind blown! @laviomri
love JSDocs!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

glad you like it!
if only there was a way to sync between the JSDoc and the documentation in the stories (like the Returns/Arguments sections), it would have been awesome

numberOfItemsInLine,
itemsCount,
getItemByIndex,
onItemClicked: ON_CLICK,
Copy link
Contributor

Choose a reason for hiding this comment

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

When developer will copy this code ON_CLICK will not be defined for him.
Form what I understood from @hadasfa presentations story should work just after copy/paste.
Maybe we need to consider to change to something like:

Suggested change
onItemClicked: ON_CLICK,
onItemClicked: () = > {console.log("item selected")},

Copy link
Contributor Author

Choose a reason for hiding this comment

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

that's a good point. the thing is that the ON_CLICK actually has some functionality (it adds an action to the "Actions" tab of the story). I also assume that the developer will have to change the callback either way (I guess they won't like a console log as a callback 😃 ).
@hadasfa what do you think about this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm gonna merge it as is for now, but if needed I'd be happy to change it in the future :)

@laviomri laviomri merged commit e70d019 into master Jan 20, 2022
@laviomri laviomri deleted the feature/omri/user-grid-keyboard-navigation branch January 20, 2022 12:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants