import type { ComponentType, ReactElement } from 'react'; import React, { useEffect, useState } from 'react'; import { LoaderRibbon } from '@teambit/base-ui.loaders.loader-ribbon'; export type LoaderProps = { /** component to render */ Target: ComponentType | undefined; /** component to render when Target is undefined */ DefaultComponent: ComponentType; /** component to render when target is missing, for a grace period, until rendering the default */ Loader?: ComponentType; /** cool-down period (in ms) to show Loader, before showing the default */ timeout?: number; }; export function LoaderFallback({ Target, Loader = LoaderComponent, DefaultComponent, timeout = 15000 }: LoaderProps) { return useFallback(Target && , , { timeout, loader: }); } export type useFallbackOptions = { timeout?: number; loader?: ReactElement }; export function useFallback( target: ReactElement | null | undefined, fallback: ReactElement, { timeout = 15000, loader = }: useFallbackOptions = {} ): ReactElement | null { const [working, setWorking] = useState(!!target); const hasTarget = !!target; useEffect(() => { if (timeout <= 0) return () => {}; if (hasTarget) { setWorking(true); return () => {}; } const tmId = setTimeout(() => setWorking(false), timeout); return () => clearTimeout(tmId); }, [hasTarget, timeout]); if (target) return target; if (working && timeout > 0) return loader; return fallback; } function LoaderComponent() { return ; }