raster-foundry / blasterjs

React UI library designed and built by Azavea
https://raster-foundry-blaster.netlify.com
Other
6 stars 3 forks source link

Add FocusVisible component #219

Closed lederer closed 5 years ago

lederer commented 5 years ago

Overview

Uses WICG's focus-visible library to suppress focus treatments on elements focused via mouse. Focus treatment is retained when focused via keyboard.

The library is wrapped in a new <FocusVisible> component that should be included as a child of the <Blaster> component when this functionality is preferred (which should be most cases).

Default focus treatment can be customized in FocusVisible's theme file.

Existing components that have a :focus treatment have been updated to use the .js-focus-visible &.focus-visible and :focus-visible selectors instead of :focus.

Since <Checkbox> and <Radio> are rendered artificially, with their underlying input elements made invisible, their focus treatments have been styled via :focus-within instead of :focus. However, there is currently no way to mimic something like :focus-visible-within. So we use a hack :( to blur the underlying <input> element immediately on focus by mouse (not kb), so the :focus-within treatment doesn't appear. This hack does not affect functionality in practice, though it's semantically incorrect.

<Select> is also rendered artificially, but the blurUnlessFocusVisible() solution above won't work across browsers. So for now <Select> is the exception and will render its focus treatment even on mouse focus.

Checklist

Upgrade instructions

If there are any of the following in this PR, provide proper instructions on how to upgrade:

Notes

Encountered and fixed a bug where <Select> wasn't passing critical form props (value, defaultValue, onChange) to the underlying <select> element.

Testing Instructions

Closes #207

lederer commented 5 years ago

~Hold off on this review until I update the docs with either a page for the FocusVisible component or instructions on the Blaster component page.~

Never mind. This isn't necessary.