Skip to content

Commit

Permalink
feat(what-input): Limit keyboard detection in inputs (#25087)
Browse files Browse the repository at this point in the history
* feat(what-input): Limit keyboard detection in inputs

* show focus indicator in dropdown scenarios

* fix test

* set what-input to mouse initially

* naming, docs and changelog

* Update packages/fluentui/react-northstar/src/utils/whatInput.ts

Co-authored-by: ling1726 <[email protected]>

Co-authored-by: Juraj Kapsiar <[email protected]>
Co-authored-by: ling1726 <[email protected]>
  • Loading branch information
3 people authored Oct 24, 2022
1 parent a64b8d5 commit d6837b7
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 2 deletions.
1 change: 1 addition & 0 deletions packages/fluentui/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- Add a new comfy layout variation for `ChatMessage` @davezuko ([#23974](https://github.com/microsoft/fluentui/pull/23974))
- Add `FocusTrapZone` prop `preventScrollOnRestoreFocus` to prevent scroll on focus when `FocusTrapZone` releases @yuanboxue-amber ([#24632](https://github.com/microsoft/fluentui/pull/24632))
- Add new style to v0 Tooltip to match v9 Tooltip @GianoglioEnrico ([#24908](https://github.com/microsoft/fluentui/pull/24908))
- Limit keyboard detection in inputs @jurokapsiar ([#25087](https://github.com/microsoft/fluentui/pull/25087))

### Fixes
- Allow React 17 in `peerDependencies` of all packages and bump react-is to 17 @TristanWatanabe ([#24356](https://github.com/microsoft/fluentui/pull/24356))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import {
UIComponentProps,
isFromKeyboard as detectIsFromKeyboard,
createShorthand,
setWhatInputSource,
} from '../../utils';
import { List, ListProps } from '../List/List';
import { DropdownItem, DropdownItemProps } from './DropdownItem';
Expand Down Expand Up @@ -1167,12 +1168,22 @@ export const Dropdown = (React.forwardRef<HTMLDivElement, DropdownProps>((props,
case keyboardKey.ArrowLeft:
e.stopPropagation();
if (!context.rtl) {
// https://github.com/testing-library/user-event/issues/709
// JSDOM does not implement `event.view` so prune this code path in test
if (process.env.NODE_ENV !== 'test') {
setWhatInputSource(e.view.document, 'keyboard');
}
trySetLastSelectedItemAsActive();
}
break;
case keyboardKey.ArrowRight:
e.stopPropagation();
if (context.rtl) {
// https://github.com/testing-library/user-event/issues/709
// JSDOM does not implement `event.view` so prune this code path in test
if (process.env.NODE_ENV !== 'test') {
setWhatInputSource(e.view.document, 'keyboard');
}
trySetLastSelectedItemAsActive();
}
break;
Expand Down
27 changes: 25 additions & 2 deletions packages/fluentui/react-northstar/src/utils/whatInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { isBrowser } from './isBrowser';
*/

// last used input type
let currentInput = 'initial';
let currentInput = 'mouse'; // assume happy path

// event buffer timer
let eventTimer = null;
Expand Down Expand Up @@ -108,6 +108,26 @@ const addListeners = (eventTarget: Window) => {
eventTarget.addEventListener('keyup', eventBuffer, true);
};

/**
*
* @param document document to apply the update to
* @param eventKey keyboard key passed from the event
* @returns true if mode should be switched, false if not (when an input-like element is focused, and the key was not a navigational key)
*/
const keyboardInputFocused = (document: Document, eventKey: number) => {
if (
document.activeElement.tagName === 'INPUT' ||
document.activeElement.tagName === 'TEXTAREA' ||
document.activeElement.getAttribute('contenteditable')
) {
return (
eventKey === 9 || // tab
eventKey === 117
); // F6
}
return true;
};

// checks conditions before updating new input
const setInput = (event: WhatInputEvents) => {
// only execute if the event buffer timer isn't running
Expand All @@ -120,7 +140,10 @@ const setInput = (event: WhatInputEvents) => {
}

const ignoreMatch = ignoreMap.indexOf(eventKey) === -1;
const shouldUpdate = (value === 'keyboard' && eventKey && ignoreMatch) || value === 'mouse' || value === 'touch';
const shouldUpdate =
(value === 'keyboard' && eventKey && ignoreMatch && keyboardInputFocused(event.view.document, eventKey)) ||
value === 'mouse' ||
value === 'touch';

if (currentInput !== value && shouldUpdate) {
currentInput = value;
Expand Down

0 comments on commit d6837b7

Please sign in to comment.