packageLink.tsx 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. import * as React from 'react';
  2. import styled from '@emotion/styled';
  3. import {trimPackage} from 'sentry/components/events/interfaces/frame/utils';
  4. import {STACKTRACE_PREVIEW_TOOLTIP_DELAY} from 'sentry/components/stacktracePreview';
  5. import Tooltip from 'sentry/components/tooltip';
  6. import overflowEllipsis from 'sentry/styles/overflowEllipsis';
  7. import space from 'sentry/styles/space';
  8. import {defined} from 'sentry/utils';
  9. type Props = {
  10. includeSystemFrames: boolean;
  11. onClick: (event: React.MouseEvent<HTMLAnchorElement>) => void;
  12. packagePath: string | null;
  13. withLeadHint: boolean;
  14. isClickable?: boolean;
  15. /**
  16. * Is the stack trace being previewed in a hovercard?
  17. */
  18. isHoverPreviewed?: boolean;
  19. };
  20. class PackageLink extends React.Component<Props> {
  21. handleClick = (event: React.MouseEvent<HTMLAnchorElement>) => {
  22. const {isClickable, onClick} = this.props;
  23. if (isClickable) {
  24. onClick(event);
  25. }
  26. };
  27. render() {
  28. const {
  29. packagePath,
  30. isClickable,
  31. withLeadHint,
  32. children,
  33. includeSystemFrames,
  34. isHoverPreviewed,
  35. } = this.props;
  36. return (
  37. <Package
  38. onClick={this.handleClick}
  39. isClickable={isClickable}
  40. withLeadHint={withLeadHint}
  41. includeSystemFrames={includeSystemFrames}
  42. >
  43. {defined(packagePath) ? (
  44. <Tooltip
  45. title={packagePath}
  46. delay={isHoverPreviewed ? STACKTRACE_PREVIEW_TOOLTIP_DELAY : undefined}
  47. >
  48. <PackageName
  49. isClickable={isClickable}
  50. withLeadHint={withLeadHint}
  51. includeSystemFrames={includeSystemFrames}
  52. >
  53. {trimPackage(packagePath)}
  54. </PackageName>
  55. </Tooltip>
  56. ) : (
  57. <span>{'<unknown>'}</span>
  58. )}
  59. {children}
  60. </Package>
  61. );
  62. }
  63. }
  64. export const Package = styled('a')<Partial<Props>>`
  65. font-size: 13px;
  66. font-weight: bold;
  67. padding: 0 0 0 ${space(0.5)};
  68. color: ${p => p.theme.textColor};
  69. :hover {
  70. color: ${p => p.theme.textColor};
  71. }
  72. cursor: ${p => (p.isClickable ? 'pointer' : 'default')};
  73. display: flex;
  74. align-items: center;
  75. ${p =>
  76. p.withLeadHint && (p.includeSystemFrames ? `max-width: 89px;` : `max-width: 76px;`)}
  77. @media (min-width: ${p => p.theme.breakpoints[2]}) and (max-width: ${p =>
  78. p.theme.breakpoints[3]}) {
  79. ${p =>
  80. p.withLeadHint && (p.includeSystemFrames ? `max-width: 76px;` : `max-width: 63px;`)}
  81. }
  82. `;
  83. export const PackageName = styled('span')<
  84. Pick<Props, 'isClickable' | 'withLeadHint' | 'includeSystemFrames'>
  85. >`
  86. max-width: ${p =>
  87. p.withLeadHint && p.isClickable && !p.includeSystemFrames ? '45px' : '104px'};
  88. ${overflowEllipsis}
  89. `;
  90. export default PackageLink;