Skip to content
Open
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
22 changes: 14 additions & 8 deletions packages/core/src/hooks/useKeyboard/useKeyboard.demo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,28 @@ import { useKeyboard } from '@siberiacancode/reactuse';
import { useState } from 'react';

const Demo = () => {
const [pressedKeys, setPressedKeys] = useState<string[]>([]);
// Use object to track both key (character) and code (physical key)
// this solves the keyboard layout switching issue
const [pressedKeys, setPressedKeys] = useState<{ key: string; code: string }[]>([]);

useKeyboard({
onKeyDown: (event) => {
onKeyDown: (event: KeyboardEvent) => {
event.preventDefault();
setPressedKeys((prevPressedKeys) => {
if (!prevPressedKeys.includes(event.key)) {
return [...prevPressedKeys, event.key];
// Check by event.code (physical key), not by event.key (character)
// this prevents duplication when switching keyboard layout
if (!prevPressedKeys.some(({ code }) => code === event.code)) {
return [...prevPressedKeys, { key: event.key, code: event.code }];
}
return prevPressedKeys;
});
},
onKeyUp: (event) => {
onKeyUp: (event: KeyboardEvent) => {
event.preventDefault();
setPressedKeys((prevPressedKeys) =>
prevPressedKeys.filter((key) => key.toLowerCase() !== event.key.toLowerCase())
// Remove by event.code to correctly handle key release
// regardless of current keyboard layout
prevPressedKeys.filter(({ code }) => code !== event.code)
);
}
});
Expand All @@ -26,8 +32,8 @@ const Demo = () => {
<div>
<span>Currently pressed keys:</span>
<div className='flex flex-wrap gap-2'>
{pressedKeys.map((key) => (
<code key={key}>{key}</code>
{pressedKeys.map(({ key, code }) => (
<code key={code}>{key}</code>
))}
</div>
</div>
Expand Down