progressBar.tsx 1.5 KB

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