breadcrumbRow.tsx 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  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) =>
  51. onInspectorExpanded && onInspectorExpanded(index, path, expandedState, e),
  52. [index, onInspectorExpanded]
  53. );
  54. const hasOccurred = currentTime >= frame.offsetMs;
  55. const isBeforeHover =
  56. currentHoverTime === undefined || currentHoverTime >= frame.offsetMs;
  57. return (
  58. <StyledTimeBorder
  59. className={classNames({
  60. beforeCurrentTime: hasOccurred,
  61. afterCurrentTime: !hasOccurred,
  62. beforeHoverTime: currentHoverTime !== undefined ? isBeforeHover : undefined,
  63. afterHoverTime: currentHoverTime !== undefined ? !isBeforeHover : undefined,
  64. })}
  65. style={style}
  66. >
  67. <BreadcrumbItem
  68. frame={frame}
  69. traces={traces}
  70. extraction={extraction}
  71. onClick={onClick}
  72. onMouseEnter={onMouseEnter}
  73. onMouseLeave={onMouseLeave}
  74. projectSlug={projectSlug}
  75. startTimestampMs={startTimestampMs}
  76. expandPaths={expandPaths}
  77. onDimensionChange={handleDimensionChange}
  78. onInspectorExpanded={handleObjectInspectorExpanded}
  79. />
  80. </StyledTimeBorder>
  81. );
  82. }
  83. const StyledTimeBorder = styled('div')`
  84. /* Overridden in TabItemContainer, depending on *CurrentTime and *HoverTime classes */
  85. border-top: 1px solid transparent;
  86. border-bottom: 1px solid transparent;
  87. `;