GithubHelp home page GithubHelp logo

sparksuite / react-accessible-dropdown-menu-hook Goto Github PK

View Code? Open in Web Editor NEW
114.0 114.0 25.0 3.97 MB

A simple Hook for creating fully accessible dropdown menus in React

Home Page: http://sparksuite.github.io/react-accessible-dropdown-menu-hook

License: MIT License

TypeScript 83.54% JavaScript 6.46% HTML 0.77% CSS 9.23%
accessibility dropdown-menus hacktoberfest react react-hooks

react-accessible-dropdown-menu-hook's People

Contributors

caryaharper avatar corymharper avatar dependabot-preview[bot] avatar dependabot[bot] avatar greenkeeper[bot] avatar jaksenko avatar msakrejda avatar wescossick avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

react-accessible-dropdown-menu-hook's Issues

Add "isOpen" indicator to demo site

Currently the isOpen return value of the hook is not being tested to check if it has the correct value at different states of the component. In order to test this a feature should be added to the demo site which as a side effect indicates the current value of isOpen.

Example:

<span id='is-open-indicator'>{isOpen ? 'true' : 'false'}</span>

Convert NPM commands to Yarn

We've generally been preferring Yarn over NPM, so it'd be great to convert all NPM commands to Yarn ones where possible in this project.

Add support for new element types for menubutton element

Currently the hook only accepts HTMLButtonElement as the typing for the ref that is applied to the element that open/closes the menu. This applies an amount of inflexibility in the implementation of hook, and could be improved to support multiple element types.

The user may need to pass some sort of option to the hook to clarify what kind of element they want to use, so that type checking can still be implemented well, it may be that only a limited number of element types can be supported.

Add documentation

We can use the README.md file to document the usage/accessibility/behavior/etc.

Greenkeeper is incompatible with Travis-CI pull request build

Issue
Currently travis.yml specifies that if the base branch is a Greenkeeper branch that it should use yarn install rather than yarn install --frozen-lockfile however, this does not work for builds for a pull request, because the base branch in that scenario is always master.

Expected behavior
If Greenkeeper upgrades a package on it's branch, the continuous integration should also upgrade that package when running it's build.

Add tests

Add in the tests and ensure they run properly with npm test. Tests should be contained within the test/ folder, and should be suffixed with .test.ts to work.

Enzyme and Puppeteer are available for use in tests, which are run by Jest.

Occasional Puppeteer test failures

The Puppeteer tests will sometimes fail, which is fixed by simply retrying. I added a wait option, but that did not fix the issue. We need to look into why this is, because it's confusing Greenkeeper and making our workflow more inefficient.

Here's some examples:

Testing has failed on both Node.js LTS and current. I'm currently seeing if it's always the same test case.

Possibility of race conditions related to item refs

Currently this is how our item refs are generated:

	// Initialize refs and update them when the item count changes
	useEffect(() => {
		itemRefs.current = Array.from({ length: itemCount }, () => createRef<HTMLAnchorElement>());
	}, [itemCount]);

As per the comment, it's even how we initially create our refs. This behavior was introduced to accommodate for implementations that might change the number of items in a menu variably. However, revisiting this code block, there are some key problems with it, specifically:

  1. The refs are held within a ref
  2. The ref is updated inside of a useEffect callback

The first is at issue because when a ref is updated, it does not force the component to update. This means that the component will not be required to have the most up to date ref array in order to finish it's render cycle. The second augments the issue making the update happen in a slightly unpredictable asynchronous manner, basically we can not guarantee the refs will be updated before the array is processed and the hook returns a value.

Solutions:

  1. Reconstruct the item refs on every recall of the hook, so instead of assigning it to a ref it would look more similar to const itemRefs = Array.from({ length: itemCount }, () => createRef<HTMLAnchorElement>()), that way it will be reevaluated accurately on every render. This could be further optimized very easily using useMemo.
  2. Convert itemRefs into state, this will guarantee the hook will return the most recent copy of the refs, but the downside is that it may result in more render cycles.

Design real demo site/content

Right now our demo website is mostly just there to enable Puppeteer testing. We need to actually populate it with a real design and appropriate content.

An in-range update of @types/react is breaking the build 🚨

The dependency @types/react was updated from 16.9.16 to 16.9.17.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

@types/react is a direct dependency of this project, and it is very likely causing it to break. If other packages depend on yours, this update is probably also breaking those in turn.

Status Details
  • continuous-integration/travis-ci/push: The Travis CI build failed (Details).

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Greenkeeper is shutting down

As Greenkeeper has mentioned in recent pull requests, and on it's website (https://greenkeeper.io/), it is shutting down, in favor of a more advanced solution with a bigger team behind it. The new solution goes a bit beyond the scope of this repository, but we would still like to have automated package updates.

Dynamic item count

Current behavior
Currently the hook initializes with a given number of items, however it is not possible to increase or decrease those items to suit a dynamic list.

Desired behavior
The hook should be able to handle lists that change in size.

Some suggestions

Accidentally pressed enter.

Edit: I'm liking this library, due to its simplicity in setting up a working dropdown menu. However, two things:

  1. I was thinking about whether you can extend this hook to include all sorts of elements, not just buttons or anchor elements.
  2. Shouldn't the esc key close the dropdown? Isn't that an accessibility feature?

Otherwise, all good! Thanks so much.

Reduce number of variables documented in some cases

Currently, the Hook returns just four variables, which isn't that many, but as we add more (like we plan to do in #282), this will grow cumbersome to document each on every time. Instead, in the most basic examples of how to use the Hook (e.g., the README and the "using" page), we should only document the three variables that are useful for basic setups: buttonProps, itemProps, and isOpen.

Those three are the only three that get referenced in the code snippets that follow those examples anyway. We never actually demonstrate usage of setIsOpen.

Further, on the "options" page, we should remove const { buttonProps, itemProps, isOpen, setIsOpen } = since it's unnecessary when all we're talking about on that page are the options.

Create demo

Create a demo that's published to GitHub pages. Something simple will do. Update the URL beneath the GitHub repository name to point to the demo.

An in-range update of @types/node is breaking the build 🚨

The dependency @types/node was updated from 12.12.20 to 12.12.21.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

@types/node is a direct dependency of this project, and it is very likely causing it to break. If other packages depend on yours, this update is probably also breaking those in turn.

Status Details
  • continuous-integration/travis-ci/push: The Travis CI build failed (Details).

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Make the menu close when an item is clicked

Currently the hook only manages closing and opening the menu element when keyboard controls are being utilized. This leaves it up to the developer to implement closing and opening their menu element when an item is clicked. This is suboptimal because they can not properly utilize the isOpen boolean value returned by the hook if the developer(s) must rely on a different value for click events.

Due to this some solution needs to be implemented to detect item clicks and close the menu in response.

Add support for new element types to be used as menu items

Currently only HTMLAnchorElements are supported for use as menu item elements with the hook. For flexibility, and as not to prescribe the implementation of the hook to developers using the package, making the ref's typing more generic but still type safe would be a warranted enhancement.

This will probably require an addition of passing generic types to the hook in order to accomplish.

Create a more limited type definition for button props

Currently, the type of the button props returned by the hook is React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>. This type definition is too broad and causes conflicts when spread with other custom props given by the developer. A more narrow definition should be created to avoid those conflicts and create a more accurate typing.

Test demo website across more OSs and devices

The demo website wasn't tested too thoroughly against mobile devices, tablets, and Windows. So we should test it more thoroughly against those OSs & devices, and make improvements as necessary.

Pay particular attention to how the footer behaves at various screen sizes.

Move demo site back to `demo/`

We originally moved the demo website from demo/ to docs/, since that's the only directory GitHub pages will pull from. However, it'd be better to reverse this and have Travis CI publish the built demo website to a gh-pages branch. That way, the built files don't have to ever live in the master branch.

Prevent unnecessary event listeners

There are indications that the useEffect on line 52 could be generating extra click event listeners every time the menu open or closes. This should be researched to determine if it is the case, and a PR opened to erect the issue.

Change instances of `fireEvent` to `userEvent.type` in testing

When we moved from from Enzyme to testing-library for testing, their user-event package, the suggested way of testing events initiated by the user, did not support ArrowDown or ArrowUp. As of version 12.5.0 they now support those events, and we should refactor our existing instances of fireEvent to be replaced with userEvent.type where we can.

Other types of menu items?

This is a question rather than strictly an issue - apologies if this muddies your issue list!

Love what you've built. I'd like to be able to use this with button components within the menu, not just links in the case of an application menu. Given your knowledge about the accessibility requirements, are there any modifications to the props handed back by this hook that would need to be made to accomplish this from an accessibility standpoint?

Thanks!

Add headless browser tests

Some of the component's behavior relies on how the browser behaves. Enzyme cannot simulate this, so we'll rely on headless browser tests for that type of testing. Before we can implement this, though, we'll need to create a demo website (#9).

Add option to choose whether to focus first item on click

In #63 we altered the hook so that the first item was not focused on click. I am proposing that this be turned into an option, and that the default behavior be that the first item is focused on click. I think that the default behavior should be focusing the first item because it is what is indicated in the WAI-ARIA Authoring Practices 1.1 section 3.15. Further because the :focus-visible selector's support is fairly good these days.

A pull request that closes this issue will have to address two main features, the first is digesting options as a parameter when the hook is initialized, and the second will be logic applying to the newly introduced option.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.