All files / libs/ext/react/hooks/src/lib/use-focus useFocus.ts

100% Statements 41/41
100% Branches 5/5
100% Functions 1/1
100% Lines 41/41

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 421x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 6x 6x 6x 6x 6x 6x 6x 2x 2x 6x 6x 6x 6x 6x 6x 2x 2x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x  
import { useCallback, type FocusEventHandler } from 'react';
 
import { useBoolState } from '../use-bool-state/useBoolState';
 
export type FocusEventHandlers<TElement extends HTMLElement> = {
  onFocus: FocusEventHandler<TElement>;
  onBlur: FocusEventHandler<TElement>;
};
 
export type UseFocusValue<TElement extends HTMLElement> = [state: boolean, eventHandlers: FocusEventHandlers<TElement>];
 
export const useFocus = <TElement extends HTMLElement>({
  onFocus,
  onBlur,
}: Partial<FocusEventHandlers<TElement>> = {}): UseFocusValue<TElement> => {
  const { isFocused, setFocusedTrue, setFocusedFalse } = useBoolState(false, 'focused');
 
  const onFocusProxy: FocusEventHandler<TElement> = useCallback(
    (event) => {
      setFocusedTrue();
      onFocus?.(event);
    },
    [setFocusedTrue, onFocus],
  );
 
  const onBlurProxy: FocusEventHandler<TElement> = useCallback(
    (event) => {
      setFocusedFalse();
      onBlur?.(event);
    },
    [setFocusedFalse, onBlur],
  );
 
  return [
    isFocused,
    {
      onFocus: onFocusProxy,
      onBlur: onBlurProxy,
    },
  ];
};