sidebarPanelItem.tsx 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import styled from '@emotion/styled';
  2. import ExternalLink from 'sentry/components/links/externalLink';
  3. import {t} from 'sentry/locale';
  4. import space from 'sentry/styles/space';
  5. type Props = {
  6. /**
  7. * Content rendered instead the panel item
  8. */
  9. children?: React.ReactNode;
  10. /**
  11. * The text for the CTA link at the bottom of the panel item
  12. */
  13. cta?: string;
  14. /**
  15. * Has the item been seen? affects the styling of the panel item
  16. */
  17. hasSeen?: boolean;
  18. /**
  19. * The URL to use for the CTA
  20. */
  21. link?: string;
  22. /**
  23. * A message with muted styling which appears above the children content
  24. */
  25. message?: React.ReactNode;
  26. /**
  27. * The title of the sidebar item
  28. */
  29. title?: string;
  30. /**
  31. * Actions to the right of the title
  32. */
  33. titleAction?: React.ReactNode;
  34. };
  35. const SidebarPanelItem = ({
  36. hasSeen,
  37. title,
  38. message,
  39. link,
  40. cta,
  41. titleAction,
  42. children,
  43. }: Props) => (
  44. <SidebarPanelItemRoot>
  45. {title && (
  46. <TitleWrapper>
  47. <Title hasSeen={hasSeen}>{title}</Title>
  48. {titleAction}
  49. </TitleWrapper>
  50. )}
  51. {message && <Message>{message}</Message>}
  52. {children}
  53. {link && (
  54. <Text>
  55. <ExternalLink href={link}>{cta || t('Read More')}</ExternalLink>
  56. </Text>
  57. )}
  58. </SidebarPanelItemRoot>
  59. );
  60. export default SidebarPanelItem;
  61. const SidebarPanelItemRoot = styled('div')`
  62. line-height: 1.5;
  63. border-top: 1px solid ${p => p.theme.innerBorder};
  64. background: ${p => p.theme.background};
  65. font-size: ${p => p.theme.fontSizeMedium};
  66. padding: ${space(3)};
  67. `;
  68. const TitleWrapper = styled('div')`
  69. display: flex;
  70. justify-content: space-between;
  71. gap: ${space(1)};
  72. `;
  73. const Title = styled('div')<Pick<Props, 'hasSeen'>>`
  74. font-size: ${p => p.theme.fontSizeLarge};
  75. margin-bottom: ${space(1)};
  76. color: ${p => p.theme.textColor};
  77. ${p => !p.hasSeen && 'font-weight: 600;'};
  78. .culprit {
  79. font-weight: normal;
  80. }
  81. `;
  82. const Text = styled('div')`
  83. margin: ${space(0.5)} 0;
  84. &:last-child {
  85. margin-bottom: 0;
  86. }
  87. `;
  88. const Message = styled(Text)`
  89. color: ${p => p.theme.subText};
  90. `;