All files / libs/ext/react/hooks/src/lib/use-bool-state useBoolState.ts

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

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 42 43 44 45 46 47 481x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 22x 22x 22x 22x 22x 22x 5x 22x 22x 22x 5x 22x 22x 22x 2x 22x 22x 22x 22x 22x 22x 22x 22x 22x 22x 22x 22x  
import { upperFirst } from 'lodash-es';
import { useCallback, useState, type Dispatch, type SetStateAction } from 'react';
import { type IsStringLiteral } from 'type-fest';
 
import { type MergeAll } from '@amalia/ext/typescript';
 
type UseBoolStateValue<TName extends string> =
  IsStringLiteral<TName> extends true
    ? MergeAll<
        [
          Record<`is${Capitalize<TName>}`, boolean>,
          Record<`set${Capitalize<TName>}`, Dispatch<SetStateAction<boolean>>>,
          Record<`set${Capitalize<TName>}True`, () => void>,
          Record<`set${Capitalize<TName>}False`, () => void>,
          Record<`toggle${Capitalize<TName>}`, () => void>,
        ]
      >
    : never;
 
export const useBoolState = <TName extends string = 'state'>(
  initialState: boolean | (() => boolean) = false,
  name: TName = 'state' as TName,
): UseBoolStateValue<TName> => {
  const [isState, setIsState] = useState<boolean>(initialState);
 
  const onTrue = useCallback(() => {
    setIsState(true);
  }, []);
 
  const onFalse = useCallback(() => {
    setIsState(false);
  }, []);
 
  const onToggle = useCallback(() => {
    setIsState((currentState) => !currentState);
  }, []);
 
  const nameUpper = upperFirst(name);
 
  return {
    [`is${nameUpper}`]: isState,
    [`set${nameUpper}`]: setIsState,
    [`set${nameUpper}True`]: onTrue,
    [`set${nameUpper}False`]: onFalse,
    [`toggle${nameUpper}`]: onToggle,
  } as UseBoolStateValue<TName>;
};