1{"version":3,"file":"useSourceSelection.js","sourceRoot":"","sources":["../../src/web/useSourceSelection.ts"],"names":[],"mappings":"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","sourcesContent":["import React, { useState, useRef } from 'react';\n\nimport { ImageProps, ImageSource } from '../Image.types';\nimport { isBlurhashString, isThumbhashString } from '../utils/resolveSources';\n\nfunction findBestSourceForSize(\n  sources: ImageSource[] | undefined,\n  size: DOMRect | null\n): ImageSource | null {\n  if (sources?.length === 1) {\n    return sources[0];\n  }\n  return (\n    [...(sources || [])]\n      // look for the smallest image that's still larger then a container\n      ?.map((source) => {\n        if (!size) {\n          return { source, penalty: 0, covers: false };\n        }\n        const { width, height } =\n          typeof source === 'object' ? source : { width: null, height: null };\n        if (width == null || height == null) {\n          return { source, penalty: 0, covers: false };\n        }\n        if (width < size.width || height < size.height) {\n          return {\n            source,\n            penalty: Math.max(size.width - width, size.height - height),\n            covers: false,\n          };\n        }\n        return { source, penalty: (width - size.width) * (height - size.height), covers: true };\n      })\n      .sort((a, b) => a.penalty - b.penalty)\n      .sort((a, b) => Number(b.covers) - Number(a.covers))[0]?.source ?? null\n  );\n}\n\nexport interface SrcSetSource extends ImageSource {\n  srcset: string;\n  sizes: string;\n  // used as key and a fallback in case srcset is not supported\n  uri: string;\n  type: 'srcset';\n}\n\nfunction getCSSMediaQueryForSource(source: ImageSource) {\n  return `(max-width: ${source.webMaxViewportWidth ?? source.width}px) ${source.width}px`;\n}\n\nfunction selectSource(\n  sources: ImageSource[] | undefined,\n  size: DOMRect | null,\n  responsivePolicy: ImageProps['responsivePolicy']\n): ImageSource | SrcSetSource | null {\n  if (sources == null || sources.length === 0) {\n    return null;\n  }\n\n  if (responsivePolicy !== 'static') {\n    return findBestSourceForSize(sources, size);\n  }\n  const staticSupportedSources = sources\n    .filter(\n      (s) => s.uri && s.width != null && !isBlurhashString(s.uri) && !isThumbhashString(s.uri)\n    )\n    .sort(\n      (a, b) => (a.webMaxViewportWidth ?? a.width ?? 0) - (b.webMaxViewportWidth ?? b.width ?? 0)\n    );\n\n  if (staticSupportedSources.length === 0) {\n    console.warn(\n      \"You've set the `static` responsivePolicy but none of the sources have the `width` properties set. Make sure you set both `width` and `webMaxViewportWidth` for best results when using static responsiveness. Falling back to the `initial` policy.\"\n    );\n    return findBestSourceForSize(sources, size);\n  }\n\n  const srcset = staticSupportedSources\n    ?.map((source) => `${source.uri} ${source.width}w`)\n    .join(', ');\n  const sizes = `${staticSupportedSources\n    ?.map(getCSSMediaQueryForSource)\n    .join(', ')}, ${staticSupportedSources[staticSupportedSources.length - 1]?.width}px`;\n  return {\n    srcset,\n    sizes,\n    uri: staticSupportedSources[staticSupportedSources.length - 1]?.uri ?? '',\n    type: 'srcset',\n  };\n}\n\ntype UseSourceSelectionReturn = {\n  containerRef: (element: HTMLDivElement) => void;\n  source: ImageSource | SrcSetSource | null;\n};\n\nexport default function useSourceSelection(\n  sources?: ImageSource[],\n  responsivePolicy: ImageProps['responsivePolicy'] = 'static',\n  measurementCallback?: (target: HTMLElement, size: DOMRect) => void\n): UseSourceSelectionReturn {\n  const hasMoreThanOneSource = (sources?.length ?? 0) > 1;\n  // null - not calculated yet, DOMRect - size available\n  const [size, setSize] = useState<null | DOMRect>(null);\n  const resizeObserver = useRef<ResizeObserver | null>(null);\n\n  React.useEffect(() => {\n    return () => {\n      resizeObserver.current?.disconnect();\n    };\n  }, []);\n\n  const containerRef = React.useCallback(\n    (element: HTMLDivElement) => {\n      // we can't short circuit here since we need to read the size for better animated transitions\n      if (!hasMoreThanOneSource && !measurementCallback) {\n        return;\n      }\n      const rect = element?.getBoundingClientRect();\n      measurementCallback?.(element, rect);\n      setSize(rect);\n\n      if (responsivePolicy === 'live') {\n        resizeObserver.current?.disconnect();\n        if (!element) {\n          return;\n        }\n        resizeObserver.current = new ResizeObserver((entries) => {\n          setSize(entries[0].contentRect);\n          measurementCallback?.(entries[0].target as any, entries[0].contentRect);\n        });\n        resizeObserver.current.observe(element);\n      }\n    },\n    [hasMoreThanOneSource, responsivePolicy]\n  );\n\n  const source = selectSource(sources, size, responsivePolicy);\n\n  return React.useMemo(\n    () => ({\n      containerRef,\n      source,\n    }),\n    [source]\n  );\n}\n"]}