loadingContainer.tsx 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. import {useTheme} from '@emotion/react';
  2. import styled from '@emotion/styled';
  3. import LoadingIndicator from 'sentry/components/loadingIndicator';
  4. export type LoadingContainerProps = {
  5. children?: React.ReactNode;
  6. className?: string;
  7. isLoading?: boolean;
  8. isReloading?: boolean;
  9. maskBackgroundColor?: string;
  10. };
  11. type MaskProps = {
  12. isReloading: boolean;
  13. maskBackgroundColor: string;
  14. };
  15. export default function LoadingContainer({
  16. isLoading = false,
  17. isReloading = false,
  18. maskBackgroundColor,
  19. className,
  20. children,
  21. }: LoadingContainerProps) {
  22. const theme = useTheme();
  23. const isLoadingOrReloading = isLoading || isReloading;
  24. return (
  25. <Container className={className}>
  26. {isLoadingOrReloading && (
  27. <div>
  28. <LoadingMask
  29. isReloading={isReloading}
  30. maskBackgroundColor={maskBackgroundColor ?? theme.white}
  31. />
  32. <Indicator />
  33. </div>
  34. )}
  35. {children}
  36. </Container>
  37. );
  38. }
  39. const Container = styled('div')`
  40. position: relative;
  41. `;
  42. const LoadingMask = styled('div')<MaskProps>`
  43. position: absolute;
  44. z-index: 1;
  45. background-color: ${p => p.maskBackgroundColor};
  46. width: 100%;
  47. height: 100%;
  48. opacity: ${p => (p.isReloading ? '0.6' : '1')};
  49. `;
  50. const Indicator = styled(LoadingIndicator)`
  51. position: absolute;
  52. z-index: 3;
  53. width: 100%;
  54. `;