objectInspector.tsx 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. import {ComponentProps, MouseEvent, useMemo} from 'react';
  2. import {useTheme} from '@emotion/react';
  3. import styled from '@emotion/styled';
  4. import {
  5. chromeDark,
  6. chromeLight,
  7. ObjectInspector as OrigObjectInspector,
  8. } from '@sentry-internal/react-inspector';
  9. import {CopyToClipboardButton} from 'sentry/components/copyToClipboardButton';
  10. import ConfigStore from 'sentry/stores/configStore';
  11. import {useLegacyStore} from 'sentry/stores/useLegacyStore';
  12. import {space} from 'sentry/styles/space';
  13. type Props = Omit<ComponentProps<typeof OrigObjectInspector>, 'theme'> & {
  14. onCopy?: (copiedCode: string) => void;
  15. showCopyButton?: boolean;
  16. theme?: Record<string, any>;
  17. };
  18. function ObjectInspector({data, onCopy, showCopyButton, theme, ...props}: Props) {
  19. const config = useLegacyStore(ConfigStore);
  20. const emotionTheme = useTheme();
  21. const isDark = config.theme === 'dark';
  22. const INSPECTOR_THEME = useMemo(
  23. () => ({
  24. ...(isDark ? chromeDark : chromeLight),
  25. // Reset some theme values
  26. BASE_COLOR: 'inherit',
  27. ERROR_COLOR: emotionTheme.red400,
  28. TREENODE_FONT_FAMILY: emotionTheme.text.familyMono,
  29. TREENODE_FONT_SIZE: 'inherit',
  30. TREENODE_LINE_HEIGHT: 'inherit',
  31. BASE_BACKGROUND_COLOR: 'none',
  32. ARROW_FONT_SIZE: '10px',
  33. OBJECT_PREVIEW_OBJECT_MAX_PROPERTIES: 1,
  34. ...theme,
  35. }),
  36. [isDark, theme, emotionTheme.red400, emotionTheme.text]
  37. );
  38. const inspector = (
  39. <OrigObjectInspector
  40. data={data}
  41. // @ts-expect-error
  42. theme={INSPECTOR_THEME}
  43. {...props}
  44. />
  45. );
  46. if (showCopyButton) {
  47. return (
  48. <Wrapper>
  49. <StyledCopyButton
  50. borderless
  51. iconSize="xs"
  52. onCopy={onCopy}
  53. size="xs"
  54. text={JSON.stringify(data, null, '\t')}
  55. />
  56. {inspector}
  57. </Wrapper>
  58. );
  59. }
  60. return inspector;
  61. }
  62. const Wrapper = styled('div')`
  63. position: relative;
  64. /*
  65. We need some minimum vertical height so the copy button has room.
  66. But don't try to use min-height because then whitespace would be inconsistent.
  67. */
  68. padding-bottom: ${space(1.5)};
  69. `;
  70. const StyledCopyButton = styled(CopyToClipboardButton)`
  71. position: absolute;
  72. top: 0;
  73. right: ${space(0.5)};
  74. `;
  75. export type OnExpandCallback = (
  76. path: string,
  77. expandedState: Record<string, boolean>,
  78. event: MouseEvent<HTMLDivElement>
  79. ) => void;
  80. export default ObjectInspector;