keyboard.ts 924 B

123456789101112131415161718192021222324252627282930
  1. import type { KeyboardEvent } from 'react'
  2. type ClearableInputElement = HTMLInputElement | HTMLTextAreaElement
  3. /**
  4. * Staged-Escape handler for search/filter inputs:
  5. * - Escape while the input has a value → clear the value (keeps focus)
  6. * - Escape while the input is empty → blur the input
  7. *
  8. * Stops propagation on Escape so the keystroke doesn't bubble to dialog/popover
  9. * close handlers when the consumer is nested inside one.
  10. *
  11. * @example
  12. * <Input
  13. * value={query}
  14. * onChange={(e) => setQuery(e.target.value)}
  15. * onKeyDown={onSearchInputEscape(query, setQuery)}
  16. * />
  17. */
  18. export const onSearchInputEscape =
  19. <T extends ClearableInputElement>(value: string, onClear: (next: string) => void) =>
  20. (event: KeyboardEvent<T>) => {
  21. if (event.key !== 'Escape') return
  22. event.stopPropagation()
  23. if (value.length > 0) {
  24. onClear('')
  25. } else {
  26. event.currentTarget.blur()
  27. }
  28. }