Skip to content

Add Typescript types definition for useKeyPress#217

Closed
magoz wants to merge 2 commits intouidotdev:mainfrom
magoz:main
Closed

Add Typescript types definition for useKeyPress#217
magoz wants to merge 2 commits intouidotdev:mainfrom
magoz:main

Conversation

@magoz
Copy link
Copy Markdown

@magoz magoz commented Aug 13, 2023

As mentioned in #216, the experimental hooks have missing type definitions. This PR adds types for useKeyPress.

@tylermcginnis
Copy link
Copy Markdown
Collaborator

Closing this since we'll most likely add types for all the experimental hooks in one go rather than one by one.

@toystars
Copy link
Copy Markdown
Contributor

Closing this since we'll most likely add types for all the experimental hooks in one go rather than one by one.

@tylermcginnis what are your thoughts about converting the hooks to typescript at source. #206 already adds type declaration but I suppose having full typescript support makes more sense. I am open to creating a PR for this, including the experimental hooks as well.

@magoz
Copy link
Copy Markdown
Author

magoz commented Aug 15, 2023

I ended up rewriting useKeyPress in typescript. Happy to help with some of the other hooks.

import { experimental_useEffectEvent as useEffectEvent, useEffect, useRef } from 'react'

// Based on:
// https://usehooks.com/usekeypress

const isKeyboardEvent = (event: Event): event is KeyboardEvent =>
  (event as KeyboardEvent)?.key !== undefined

export function useKeyPress(
  key: string,
  cb: (e: Event) => void,
  options?: {
    event?: keyof GlobalEventHandlersEventMap
    target?: Window | HTMLElement
    eventOptions?: AddEventListenerOptions
  }
) {
  const { event = 'keydown', eventOptions } = options ?? {}
  const eventOptionsRef = useRef(eventOptions)

  const onEvent: EventListener = useEffectEvent((event: Event) => {
    if (isKeyboardEvent(event) && event.key === key) {
      cb(event)
    }
  })

  useEffect(() => {
    const target = options?.target ?? window
    target.addEventListener(event, onEvent, eventOptionsRef.current)

    return () => {
      target.removeEventListener(event, onEvent)
    }
  }, [options?.target, event, onEvent])
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants