breadcrumbRow.tsx 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. import type {CSSProperties, MouseEvent} from 'react';
  2. import {useCallback} from 'react';
  3. import styled from '@emotion/styled';
  4. import classNames from 'classnames';
  5. import BreadcrumbItem from 'sentry/components/replays/breadcrumbs/breadcrumbItem';
  6. import {useReplayContext} from 'sentry/components/replays/replayContext';
  7. import type {Extraction} from 'sentry/utils/replays/extractDomNodes';
  8. import useCrumbHandlers from 'sentry/utils/replays/hooks/useCrumbHandlers';
  9. import type {ReplayFrame} from 'sentry/utils/replays/types';
  10. import type {ReplayTraceRow} from 'sentry/views/replays/detail/perfTable/useReplayPerfData';
  11. interface Props {
  12. extraction: Extraction | undefined;
  13. frame: ReplayFrame;
  14. index: number;
  15. onClick: ReturnType<typeof useCrumbHandlers>['onClickTimestamp'];
  16. onDimensionChange: (index: number) => void;
  17. onInspectorExpanded: (
  18. index: number,
  19. path: string,
  20. expandedState: Record<string, boolean>,
  21. event: MouseEvent<HTMLDivElement>
  22. ) => void;
  23. projectSlug: string | undefined;
  24. startTimestampMs: number;
  25. style: CSSProperties;
  26. traces: ReplayTraceRow | undefined;
  27. breadcrumbIndex?: number[][];
  28. expandPaths?: string[];
  29. }
  30. export default function BreadcrumbRow({
  31. expandPaths,
  32. extraction,
  33. frame,
  34. index,
  35. onClick,
  36. onDimensionChange,
  37. onInspectorExpanded,
  38. projectSlug,
  39. startTimestampMs,
  40. style,
  41. traces,
  42. }: Props) {
  43. const {currentTime, currentHoverTime} = useReplayContext();
  44. const {onMouseEnter, onMouseLeave} = useCrumbHandlers();
  45. const handleDimensionChange = useCallback(
  46. () => onDimensionChange(index),
  47. [onDimensionChange, index]
  48. );
  49. const handleObjectInspectorExpanded = useCallback(
  50. (path, expandedState, e) => onInspectorExpanded?.(index, path, expandedState, e),
  51. [index, onInspectorExpanded]
  52. );
  53. const hasOccurred = currentTime >= frame.offsetMs;
  54. const isBeforeHover =
  55. currentHoverTime === undefined || currentHoverTime >= frame.offsetMs;
  56. return (
  57. <StyledTimeBorder
  58. className={classNames({
  59. beforeCurrentTime: hasOccurred,
  60. afterCurrentTime: !hasOccurred,
  61. beforeHoverTime: currentHoverTime !== undefined ? isBeforeHover : undefined,
  62. afterHoverTime: currentHoverTime !== undefined ? !isBeforeHover : undefined,
  63. })}
  64. style={style}
  65. >
  66. <BreadcrumbItem
  67. frame={frame}
  68. traces={traces}
  69. extraction={extraction}
  70. onClick={onClick}
  71. onMouseEnter={onMouseEnter}
  72. onMouseLeave={onMouseLeave}
  73. projectSlug={projectSlug}
  74. startTimestampMs={startTimestampMs}
  75. expandPaths={expandPaths}
  76. onDimensionChange={handleDimensionChange}
  77. onInspectorExpanded={handleObjectInspectorExpanded}
  78. />
  79. </StyledTimeBorder>
  80. );
  81. }
  82. const StyledTimeBorder = styled('div')`
  83. /* Overridden in TabItemContainer, depending on *CurrentTime and *HoverTime classes */
  84. border-top: 1px solid transparent;
  85. border-bottom: 1px solid transparent;
  86. `;