progressBar.tsx 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. import React from 'react';
  2. import styled from '@emotion/styled';
  3. import {Theme} from 'app/utils/theme';
  4. type Variant = 'small' | 'large';
  5. type Props = {
  6. /**
  7. * The value of the progress indicator for the determinate variant. Value between 0 and 100
  8. */
  9. value: number;
  10. /**
  11. * The style of the progressBar
  12. */
  13. variant?: Variant;
  14. /**
  15. * Styles applied to the component's root
  16. */
  17. className?: string;
  18. };
  19. const getVariantStyle = ({
  20. variant = 'small',
  21. theme,
  22. }: Pick<Props, 'variant'> & {theme: Theme}) => {
  23. if (variant === 'large') {
  24. return `
  25. height: 24px;
  26. border-radius: 24px;
  27. border: 1px solid ${theme.border};
  28. box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.06);
  29. :before {
  30. left: 6px;
  31. right: 6px;
  32. height: 14px;
  33. top: calc(50% - 14px/2);
  34. border-radius: 20px;
  35. max-width: calc(100% - 12px);
  36. }
  37. `;
  38. }
  39. return `
  40. height: 6px;
  41. border-radius: 100px;
  42. background: ${theme.progressBackground};
  43. :before {
  44. top: 0;
  45. left: 0;
  46. height: 100%;
  47. }
  48. `;
  49. };
  50. const ProgressBar = styled(({className, value}: Props) => (
  51. <div
  52. role="progressbar"
  53. aria-valuenow={value}
  54. aria-valuemin={0}
  55. aria-valuemax={100}
  56. className={className}
  57. />
  58. ))`
  59. width: 100%;
  60. overflow: hidden;
  61. position: relative;
  62. :before {
  63. content: ' ';
  64. width: ${p => p.value}%;
  65. background-color: ${p => p.theme.progressBar};
  66. position: absolute;
  67. }
  68. ${getVariantStyle};
  69. `;
  70. export default ProgressBar;