gridlines.tsx 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. import React from 'react';
  2. import styled from '@emotion/styled';
  3. import * as Timeline from 'sentry/components/replays/breadcrumbs/timeline';
  4. import {countColumns, formatTime} from 'sentry/components/replays/utils';
  5. type LineStyle = 'dotted' | 'solid' | 'none';
  6. const Line = styled(Timeline.Col)<{lineStyle: LineStyle}>`
  7. border-right: 1px ${p => p.lineStyle} ${p => p.theme.gray100};
  8. text-align: right;
  9. line-height: 14px;
  10. `;
  11. function Gridlines({
  12. children,
  13. cols,
  14. lineStyle,
  15. remaining,
  16. }: {
  17. cols: number;
  18. lineStyle: LineStyle;
  19. remaining: number;
  20. children?: (i: number) => React.ReactNode;
  21. }) {
  22. return (
  23. <Timeline.Columns totalColumns={cols} remainder={remaining}>
  24. {[...Array(cols)].map((_, i) => (
  25. <Line key={i} lineStyle={lineStyle}>
  26. {children ? children(i) : null}
  27. </Line>
  28. ))}
  29. </Timeline.Columns>
  30. );
  31. }
  32. type Props = {
  33. durationMs: number;
  34. width: number;
  35. minWidth?: number;
  36. };
  37. export function MajorGridlines({durationMs, minWidth = 50, width}: Props) {
  38. const {timespan, cols, remaining} = countColumns(durationMs, width, minWidth);
  39. return (
  40. <Gridlines cols={cols} lineStyle="solid" remaining={remaining}>
  41. {i => <Label>{formatTime((i + 1) * timespan)}</Label>}
  42. </Gridlines>
  43. );
  44. }
  45. export function MinorGridlines({durationMs, minWidth = 20, width}: Props) {
  46. const {cols, remaining} = countColumns(durationMs, width, minWidth);
  47. return <Gridlines cols={cols} lineStyle="dotted" remaining={remaining} />;
  48. }
  49. const Label = styled('small')`
  50. font-variant-numeric: tabular-nums;
  51. font-size: ${p => p.theme.fontSizeSmall};
  52. `;