/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import React, { useEffect, useState } from 'react'; import { styled, logging } from '@superset-ui/core'; export type BackgroundPosition = 'top' | 'bottom'; interface ImageContainerProps { src: string; position: BackgroundPosition; } const ImageContainer = styled.div` background-image: url(${({ src }) => src}); background-size: cover; background-position: center ${({ position }) => position}; display: inline-block; height: calc(100% - 1px); width: calc(100% - 2px); margin: 1px 1px 0 1px; `; interface ImageLoaderProps extends React.DetailedHTMLProps< React.HTMLAttributes, HTMLDivElement > { fallback: string; src: string; isLoading?: boolean; position: BackgroundPosition; } export default function ImageLoader({ src, fallback, isLoading, position, ...rest }: ImageLoaderProps) { const [imgSrc, setImgSrc] = useState(fallback); useEffect(() => { if (src) { fetch(src) .then(response => response.blob()) .then(blob => { if (/image/.test(blob.type)) { const imgURL = URL.createObjectURL(blob); setImgSrc(imgURL); } }) .catch(errMsg => { logging.error(errMsg); setImgSrc(fallback); }); } return () => { // theres a very brief period where isLoading is false and this component is about to unmount // where the stale imgSrc is briefly rendered. Setting imgSrc to fallback smoothes the transition. setImgSrc(fallback); }; }, [src, fallback]); return ( ); }