{"version":3,"sources":["../src/use-image.ts"],"sourcesContent":["import { useSafeLayoutEffect } from \"@chakra-ui/react-use-safe-layout-effect\"\nimport { useCallback, useEffect, useRef, useState } from \"react\"\n\ntype NativeImageProps = React.ImgHTMLAttributes<HTMLImageElement>\n\nexport interface UseImageProps {\n  /**\n   * The image `src` attribute\n   */\n  src?: string\n  /**\n   * The image `srcset` attribute\n   */\n  srcSet?: string\n  /**\n   * The image `sizes` attribute\n   */\n  sizes?: string\n  /**\n   * A callback for when the image `src` has been loaded\n   */\n  onLoad?: NativeImageProps[\"onLoad\"]\n  /**\n   * A callback for when there was an error loading the image `src`\n   */\n  onError?: NativeImageProps[\"onError\"]\n  /**\n   * If `true`, opt out of the `fallbackSrc` logic and use as `img`\n   *\n   * @default false\n   */\n  ignoreFallback?: boolean\n  /**\n   * The key used to set the crossOrigin on the HTMLImageElement into which the image will be loaded.\n   * This tells the browser to request cross-origin access when trying to download the image data.\n   */\n  crossOrigin?: NativeImageProps[\"crossOrigin\"]\n  loading?: NativeImageProps[\"loading\"]\n}\n\ntype Status = \"loading\" | \"failed\" | \"pending\" | \"loaded\"\n\nexport type FallbackStrategy = \"onError\" | \"beforeLoadOrError\"\n\ntype ImageEvent = React.SyntheticEvent<HTMLImageElement, Event>\n\n/**\n * React hook that loads an image in the browser,\n * and lets us know the `status` so we can show image\n * fallback if it is still `pending`\n *\n * @returns the status of the image loading progress\n *\n * @example\n *\n * ```jsx\n * function App(){\n *   const status = useImage({ src: \"image.png\" })\n *   return status === \"loaded\" ? <img src=\"image.png\" /> : <Placeholder />\n * }\n * ```\n */\nexport function useImage(props: UseImageProps) {\n  const {\n    loading,\n    src,\n    srcSet,\n    onLoad,\n    onError,\n    crossOrigin,\n    sizes,\n    ignoreFallback,\n  } = props\n\n  const [status, setStatus] = useState<Status>(\"pending\")\n\n  useEffect(() => {\n    setStatus(src ? \"loading\" : \"pending\")\n  }, [src])\n\n  const imageRef = useRef<HTMLImageElement | null>()\n\n  const load = useCallback(() => {\n    if (!src) return\n\n    flush()\n\n    const img = new Image()\n    img.src = src\n    if (crossOrigin) img.crossOrigin = crossOrigin\n    if (srcSet) img.srcset = srcSet\n    if (sizes) img.sizes = sizes\n    if (loading) img.loading = loading\n\n    img.onload = (event) => {\n      flush()\n      setStatus(\"loaded\")\n      onLoad?.(event as unknown as ImageEvent)\n    }\n    img.onerror = (error) => {\n      flush()\n      setStatus(\"failed\")\n      onError?.(error as any)\n    }\n\n    imageRef.current = img\n  }, [src, crossOrigin, srcSet, sizes, onLoad, onError, loading])\n\n  const flush = () => {\n    if (imageRef.current) {\n      imageRef.current.onload = null\n      imageRef.current.onerror = null\n      imageRef.current = null\n    }\n  }\n\n  useSafeLayoutEffect(() => {\n    /**\n     * If user opts out of the fallback/placeholder\n     * logic, let's bail out.\n     */\n    if (ignoreFallback) return undefined\n\n    if (status === \"loading\") {\n      load()\n    }\n    return () => {\n      flush()\n    }\n  }, [status, load, ignoreFallback])\n\n  /**\n   * If user opts out of the fallback/placeholder\n   * logic, let's just return 'loaded'\n   */\n  return ignoreFallback ? \"loaded\" : status\n}\n\nexport const shouldShowFallbackImage = (\n  status: Status,\n  fallbackStrategy: FallbackStrategy,\n) =>\n  (status !== \"loaded\" && fallbackStrategy === \"beforeLoadOrError\") ||\n  (status === \"failed\" && fallbackStrategy === \"onError\")\n\nexport type UseImageReturn = ReturnType<typeof useImage>\n"],"mappings":";;;AAAA,SAAS,2BAA2B;AACpC,SAAS,aAAa,WAAW,QAAQ,gBAAgB;AA6DlD,SAAS,SAAS,OAAsB;AAC7C,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAEJ,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAiB,SAAS;AAEtD,YAAU,MAAM;AACd,cAAU,MAAM,YAAY,SAAS;AAAA,EACvC,GAAG,CAAC,GAAG,CAAC;AAER,QAAM,WAAW,OAAgC;AAEjD,QAAM,OAAO,YAAY,MAAM;AAC7B,QAAI,CAAC;AAAK;AAEV,UAAM;AAEN,UAAM,MAAM,IAAI,MAAM;AACtB,QAAI,MAAM;AACV,QAAI;AAAa,UAAI,cAAc;AACnC,QAAI;AAAQ,UAAI,SAAS;AACzB,QAAI;AAAO,UAAI,QAAQ;AACvB,QAAI;AAAS,UAAI,UAAU;AAE3B,QAAI,SAAS,CAAC,UAAU;AACtB,YAAM;AACN,gBAAU,QAAQ;AAClB,uCAAS;AAAA,IACX;AACA,QAAI,UAAU,CAAC,UAAU;AACvB,YAAM;AACN,gBAAU,QAAQ;AAClB,yCAAU;AAAA,IACZ;AAEA,aAAS,UAAU;AAAA,EACrB,GAAG,CAAC,KAAK,aAAa,QAAQ,OAAO,QAAQ,SAAS,OAAO,CAAC;AAE9D,QAAM,QAAQ,MAAM;AAClB,QAAI,SAAS,SAAS;AACpB,eAAS,QAAQ,SAAS;AAC1B,eAAS,QAAQ,UAAU;AAC3B,eAAS,UAAU;AAAA,IACrB;AAAA,EACF;AAEA,sBAAoB,MAAM;AAKxB,QAAI;AAAgB,aAAO;AAE3B,QAAI,WAAW,WAAW;AACxB,WAAK;AAAA,IACP;AACA,WAAO,MAAM;AACX,YAAM;AAAA,IACR;AAAA,EACF,GAAG,CAAC,QAAQ,MAAM,cAAc,CAAC;AAMjC,SAAO,iBAAiB,WAAW;AACrC;AAEO,IAAM,0BAA0B,CACrC,QACA,qBAEC,WAAW,YAAY,qBAAqB,uBAC5C,WAAW,YAAY,qBAAqB;","names":[]}