All files switch.tsx

100% Statements 21/21
100% Branches 18/18
100% Functions 4/4
100% Lines 21/21

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      1x 7x 7x   7x 7x 9x 3x   9x 5x 5x 5x 3x 3x     6x   7x                     1x 6x 6x 6x     1x 3x    
import type { FC, PropsWithChildren } from 'react';
 
type Child = typeof Case | typeof Default;
export const Switch: FC<PropsWithChildren<{}>> = ({ children }) => {
  let matchChild: Child | null = null;
  let defaultCase: typeof Default | null = null;
 
  const childs = Array.isArray(children) ? children : [children];
  childs.some((child) => {
    if (!defaultCase && child && child.type === Default) {
      defaultCase = child;
    }
    if (child && child.type === Case) {
      const { condition } = child.props;
      const conditionIsTrue = Boolean(condition);
      if (conditionIsTrue) {
        matchChild = child;
        return true;
      }
    }
    return false;
  });
  return matchChild ?? defaultCase ?? null;
};
 
type TagType = React.ElementType | keyof JSX.IntrinsicElements;
interface CaseElementProps<T extends TagType> {
  as?: T;
  readonly condition?: boolean;
}
 
export type CaseProps<T extends TagType> = CaseElementProps<T> & React.ComponentPropsWithoutRef<T>;
 
export const Case = <T extends TagType>(props: CaseProps<T>) => {
  const { children, condition, as: Comp, ...reset } = props;
  const Elm = Comp as TagType;
  return Elm ? <Elm {...reset}>{children}</Elm> : children;
};
 
export const Default = <T extends TagType>(props: Omit<CaseProps<T>, 'condition'>) => (
  <Case {...({ ...props } as CaseProps<T>)} />
);