Skip to content

feat(useKeyPress): 添加observe属性控制keyPress 全局监听 #2365

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

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
24 changes: 24 additions & 0 deletions packages/hooks/src/useKeyPress/__tests__/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,30 @@ describe('useKeyPress ', () => {
unmount();
});

it('test single key by observe', async () => {
const callbackDefault = jest.fn();
const callbackFalse = jest.fn();
const callbackTrue = jest.fn();
const hook1 = renderHook(() => useKeyPress(['c'], callbackDefault));
const hook2 = renderHook(() =>
useKeyPress(['c'], callbackFalse, {
observe: false,
}),
);
const hook3 = renderHook(() =>
useKeyPress(['c'], callbackTrue, {
observe: true,
}),
);
fireEvent.keyDown(document, { key: 'c', keyCode: 67 });
expect(callbackDefault.mock.calls.length).toBe(1);
expect(callbackFalse.mock.calls.length).toBe(0);
expect(callbackTrue.mock.calls.length).toBe(1);
hook1.unmount();
hook2.unmount();
hook3.unmount();
});

it('test modifier key', async () => {
const { unmount } = renderHook(() => useKeyPress(['ctrl'], callback));
fireEvent.keyDown(document, { key: 'ctrl', keyCode: 17, ctrlKey: true });
Expand Down
31 changes: 31 additions & 0 deletions packages/hooks/src/useKeyPress/demo/demo9.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React, { useState } from 'react';
import { useBoolean, useKeyPress } from 'ahooks';
import { Switch } from 'antd';

export default () => {
const [counter, setCounter] = useState(0);
const [observe, { toggle }] = useBoolean(true);

useKeyPress(
'w',
() => {
setCounter((prev) => prev + 1);
},
{
observe,
},
);

return (
<div>
<div>
Switch observe state &nbsp;
<Switch checked={observe} onChange={toggle} />
</div>
<div>Press [w] to increase when observe state is checked</div>
<div>
counter: <span style={{ color: '#f00' }}>{counter}</span>
</div>
</div>
);
};
5 changes: 5 additions & 0 deletions packages/hooks/src/useKeyPress/index.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ Listen for the keyboard press, support key combinations, and support alias.

<code src="./demo/demo8.tsx" />

### Control observe state

<code src="./demo/demo9.tsx" />

### Custom method

<code src="./demo/demo4.tsx" />
Expand Down Expand Up @@ -66,6 +70,7 @@ useKeyPress(
| target | DOM element or ref | `() => Element` \| `Element` \| `MutableRefObject<Element>` | - |
| exactMatch | Exact match. If set `true`, the event will only be trigger when the keys match exactly. For example, pressing [shift + c] will not trigger [c] | `boolean` | `false` |
| useCapture | to block events bubbling | `boolean` | `false` |
| observe | to control the observe state. If set `false`, the callback will not be triggered. | `boolean` | `true` |

## Remarks

Expand Down
14 changes: 12 additions & 2 deletions packages/hooks/src/useKeyPress/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export type Options = {
target?: Target;
exactMatch?: boolean;
useCapture?: boolean;
observe?: boolean;
};

// 键盘事件 keyCode 别名
Expand Down Expand Up @@ -225,12 +226,21 @@ function useKeyPress(
eventHandler: (event: KeyboardEvent, key: KeyType) => void,
option?: Options,
) {
const { events = defaultEvents, target, exactMatch = false, useCapture = false } = option || {};
const {
events = defaultEvents,
target,
exactMatch = false,
useCapture = false,
observe = true,
} = option || {};
const eventHandlerRef = useLatest(eventHandler);
const keyFilterRef = useLatest(keyFilter);

useDeepCompareEffectWithTarget(
() => {
if (!observe) {
return;
}
const el = getTargetElement(target, window);
if (!el) {
return;
Expand All @@ -255,7 +265,7 @@ function useKeyPress(
}
};
},
[events],
[events, observe],
target,
);
}
Expand Down
5 changes: 5 additions & 0 deletions packages/hooks/src/useKeyPress/index.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ nav:

<code src="./demo/demo8.tsx" />

### 控制监听状态

<code src="./demo/demo9.tsx" />

### 自定义监听方式

<code src="./demo/demo4.tsx" />
Expand Down Expand Up @@ -66,6 +70,7 @@ useKeyPress(
| target | DOM 节点或者 ref | `() => Element` \| `Element` \| `MutableRefObject<Element>` | - |
| exactMatch | 精确匹配。如果开启,则只有在按键完全匹配的情况下触发事件。比如按键 [shift + c] 不会触发 [c] | `boolean` | `false` |
| useCapture | 是否阻止事件冒泡 | `boolean` | `false` |
| observe | 是否开启监听状态,为 false 时不会触发回调函数 | `boolean` | `true` |

## Remarks

Expand Down