placeholder.tsx 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. import React from 'react';
  2. import styled from '@emotion/styled';
  3. import space from 'app/styles/space';
  4. const defaultProps = {
  5. shape: 'rect' as 'rect' | 'circle',
  6. bottomGutter: 0 as Parameters<typeof space>[0],
  7. width: '100%',
  8. height: '60px',
  9. testId: 'loading-placeholder',
  10. };
  11. type DefaultProps = Readonly<typeof defaultProps>;
  12. type Props = {
  13. className?: string;
  14. children?: React.ReactNode;
  15. error?: React.ReactNode;
  16. testId?: string;
  17. } & Partial<DefaultProps>;
  18. const Placeholder = styled(({className, children, error, testId}: Props) => {
  19. return (
  20. <div data-test-id={testId} className={className}>
  21. {error || children}
  22. </div>
  23. );
  24. })<Props>`
  25. display: flex;
  26. flex-direction: column;
  27. flex-shrink: 0;
  28. justify-content: center;
  29. align-items: center;
  30. background-color: ${p => (p.error ? p.theme.red100 : p.theme.backgroundSecondary)};
  31. ${p => p.error && `color: ${p.theme.red200};`}
  32. width: ${p => p.width};
  33. height: ${p => p.height};
  34. ${p => (p.shape === 'circle' ? 'border-radius: 100%;' : '')}
  35. ${p =>
  36. typeof p.bottomGutter === 'number' && p.bottomGutter > 0
  37. ? `margin-bottom: ${space(p.bottomGutter)};`
  38. : ''}
  39. `;
  40. Placeholder.defaultProps = defaultProps;
  41. export default Placeholder;