Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions packages/hooks/src/useKeyPress/__tests__/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,21 @@ describe('useKeyPress ', () => {
fireEvent.keyUp(document, { key: 'meta', keyCode: 91, metaKey: false });
expect(callback).toBeCalled();
});

it.only('test callback code', async () => {
let keyCode;
renderHook(() =>
useKeyPress(
['uparrow'],
(e, code) => {
keyCode = code;
},
{
events: ['keydown'],
},
),
);
fireEvent.keyDown(document, { key: 'ArrowUp', keyCode: 38, metaKey: true, shiftKey: true });
expect(keyCode).toStrictEqual(['meta', 'shift', 'arrowup']);
});
});
4 changes: 2 additions & 2 deletions packages/hooks/src/useKeyPress/index.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ type KeyFilter = keyType | keyType[] | ((event: KeyboardEvent) => boolean);

useKeyPress(
keyFilter: KeyFilter,
eventHandler: EventHandler,
eventHandler: (event: KeyboardEvent, code: string[]) => void,
options?: Options
);
```
Expand All @@ -51,7 +51,7 @@ useKeyPress(
| Property | Description | Type | Default |
| ------------ | ---------------------------------------------------------------- | --------------------------------------------------------------- | ------- |
| keyFilter | Support keyCode、alias、combination keys、array、custom function | `keyType` \| `keyType[]` \| `(event: KeyboardEvent) => boolean` | - |
| eventHandler | Callback function | `(event: KeyboardEvent) => void` | - |
| eventHandler | Callback function | `(event: KeyboardEvent, code: string[]) => void` | - |
| options | advanced options | `Options` | - |

### Options
Expand Down
28 changes: 16 additions & 12 deletions packages/hooks/src/useKeyPress/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import { getTargetElement } from '../utils/domTarget';
import useDeepCompareEffectWithTarget from '../utils/useDeepCompareWithTarget';
import isAppleDevice from '../utils/isAppleDevice';

export type KeyPredicate = (event: KeyboardEvent) => boolean;
export type KeyPredicate = (event: KeyboardEvent) => string | number | false;
export type keyType = number | string;
export type KeyFilter = keyType | keyType[] | ((event: KeyboardEvent) => boolean);
export type KeyFilter = keyType | keyType[] | ((event: KeyboardEvent) => string | number);
export type EventHandler = (event: KeyboardEvent) => void;
export type KeyEvent = 'keydown' | 'keyup';

Expand Down Expand Up @@ -155,17 +155,16 @@ function countKeyByEvent(event: KeyboardEvent) {
* 判断按键是否激活
* @param [event: KeyboardEvent]键盘事件
* @param [keyFilter: any] 当前键
* @returns Boolean
* @returns string | number | false
*/
function genFilterKey(event: KeyboardEvent, keyFilter: keyType, exactMatch: boolean) {
// 浏览器自动补全 input 的时候,会触发 keyDown、keyUp 事件,但此时 event.key 等为空
if (!event.key) {
return false;
}

// 数字类型直接匹配事件的 keyCode
if (isNumber(keyFilter)) {
return event.keyCode === keyFilter;
return event.keyCode === keyFilter ? keyFilter : false;
}

// 字符串依次判断是否有组合键
Expand All @@ -190,9 +189,9 @@ function genFilterKey(event: KeyboardEvent, keyFilter: keyType, exactMatch: bool
* 主要用来防止按组合键其子集也会触发的情况,例如监听 ctrl+a 会触发监听 ctrl 和 a 两个键的事件。
*/
if (exactMatch) {
return genLen === genArr.length && countKeyByEvent(event) === genArr.length;
return genLen === genArr.length && countKeyByEvent(event) === genArr.length ? keyFilter : false;
}
return genLen === genArr.length;
return genLen === genArr.length ? keyFilter : false;
}

/**
Expand All @@ -209,14 +208,18 @@ function genKeyFormatter(keyFilter: KeyFilter, exactMatch: boolean): KeyPredicat
}
if (Array.isArray(keyFilter)) {
return (event: KeyboardEvent) =>
keyFilter.some((item) => genFilterKey(event, item, exactMatch));
keyFilter.find((item) => genFilterKey(event, item, exactMatch))!;
}
return () => Boolean(keyFilter);
return () => (Boolean(keyFilter) ? keyFilter : false);
}

const defaultEvents: KeyEvent[] = ['keydown'];

function useKeyPress(keyFilter: KeyFilter, eventHandler: EventHandler, option?: Options) {
function useKeyPress(
keyFilter: KeyFilter,
eventHandler: (event: KeyboardEvent, code: keyType) => void,
option?: Options,
) {
const { events = defaultEvents, target, exactMatch = false, useCapture = false } = option || {};
const eventHandlerRef = useLatest(eventHandler);
const keyFilterRef = useLatest(keyFilter);
Expand All @@ -230,8 +233,9 @@ function useKeyPress(keyFilter: KeyFilter, eventHandler: EventHandler, option?:

const callbackHandler = (event: KeyboardEvent) => {
const genGuard: KeyPredicate = genKeyFormatter(keyFilterRef.current, exactMatch);
if (genGuard(event)) {
return eventHandlerRef.current?.(event);
const code = genGuard(event);
if (code) {
return eventHandlerRef.current?.(event, code);
}
};

Expand Down
4 changes: 2 additions & 2 deletions packages/hooks/src/useKeyPress/index.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ type KeyFilter = keyType | keyType[] | ((event: KeyboardEvent) => boolean);

useKeyPress(
keyFilter: KeyFilter,
eventHandler: EventHandler,
eventHandler: (event: KeyboardEvent, code: string[]) => void,
options?: Options
);
```
Expand All @@ -51,7 +51,7 @@ useKeyPress(
| 参数 | 说明 | 类型 | 默认值 |
| ------------ | -------------------------------------------- | --------------------------------------------------------------- | ------ |
| keyFilter | 支持 keyCode、别名、组合键、数组,自定义函数 | `keyType` \| `keyType[]` \| `(event: KeyboardEvent) => boolean` | - |
| eventHandler | 回调函数 | `(event: KeyboardEvent) => void` | - |
| eventHandler | 回调函数 | `(event: KeyboardEvent, code: string[]) => void` | - |
| options | 可选配置项 | `Options` | - |

### Options
Expand Down