import {
  Children,
  ComponentType,
  isValidElement,
  ReactElement,
  ReactNode,
} from 'react';

export function createChildSlot<P>(name?: string) {
  const Slot: ComponentType<P> & {
    isElementOf: (el: ReactElement) => el is ReactElement<P>;
    findElement: (
      children?: ReactNode | ReactNode[],
    ) => ReactElement<P> | undefined;
  } = () => null;
  Slot.displayName = name;

  Slot.isElementOf = (el): el is ReactElement<P> => el.type === Slot;

  Slot.findElement = (children) =>
    children != null
      ? Children.toArray(children).find(
          (child): child is ReactElement<P> =>
            isValidElement(child) && Slot.isElementOf(child),
        )
      : undefined;

  return Slot;
}
