formaat-design / reshaped

Community repository for storing examples, reporting issues and tracking roadmap
https://reshaped.so
97 stars 3 forks source link

Continuous key presses in React #253

Closed noob2 closed 1 month ago

noob2 commented 1 month ago

Is your feature request related to a problem? Please describe. I'm always frustrated when I want to handle continuous key presses in React using the useHotkeys hook from Reshaped, but the library only supports single event triggers per key press. This limitation requires additional complex setups for continuous action scenarios, such as holding down an arrow key to continuously move an object.

Describe the solution you'd like I would like the useHotkeys hook to include a new option, such as continuousKeyPresses: true, to support continuous key press handling directly within the hook. This enhancement would eliminate the need for additional complex state management or intervals.

Describe alternatives you've considered As an alternative, I'm using a combination of state hooks and setInterval to simulate continuous key press detection:

const { checkHotkeyState } = useHotkeys(
  {
      ArrowUp: () => updatePosition(1),
      ArrowDown: () => updatePosition(-1),
  }, []);

function updatePosition(delta: number) {
  // do some stuff

  setTimeout(() => {
      if (checkHotkeyState('ArrowUp')) updatePosition(1);
      if (checkHotkeyState('ArrowDown')) updatePosition(-1);
  }, 60);
}

Additional context Adding this feature would simplify implementations that require dynamic and continuous user interactions, such as games, interactive maps, or any application requiring smooth, sustained input handling. This enhancement would make Reshaped more versatile.

blvdmitry commented 1 month ago

@noob2 current implementation seems more like an incorrect behavior to me since it's meant to handle some of the edge cases related to MacOS not firing keyup events while meta key is pressed. Because of that, I've looked into changing the code to make the functionality you described work this way by default.

Would that work for your use case or can you think of examples where triggering the callback just once would be required?

noob2 commented 1 month ago

@blvdmitry making it default behavior will work properly for all my use cases.

blvdmitry commented 1 month ago

This change should be out now in 2.11.10 Let me know if you encounter any edge cases