jsxNode.tsx 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. import {Fragment, ReactNode} from 'react';
  2. import styled from '@emotion/styled';
  3. import JSXProperty from 'sentry/components/stories/jsxProperty';
  4. import {space} from 'sentry/styles/space';
  5. interface Props {
  6. name: string;
  7. children?: ReactNode;
  8. props?: Record<string, unknown>;
  9. }
  10. export default function JSXNode({name, props = {}, children}: Props) {
  11. if (children) {
  12. return (
  13. <Code data-node>
  14. {`<${name}`}
  15. {Object.entries(props).map(([propName, value]) => (
  16. <Fragment key={propName}>
  17. {' '}
  18. <JSXProperty name={propName} value={value} />
  19. </Fragment>
  20. ))}
  21. {`>`}
  22. <br />
  23. {children}
  24. <br />
  25. {`</${name}>`}
  26. </Code>
  27. );
  28. }
  29. return (
  30. <Code data-node>
  31. {`<${name} `}
  32. {Object.entries(props).map(([propName, value]) => (
  33. <Fragment key={propName}>
  34. <JSXProperty name={propName} value={value} />{' '}
  35. </Fragment>
  36. ))}
  37. {`/>`}
  38. </Code>
  39. );
  40. }
  41. const Code = styled('code')`
  42. font-size: ${p => p.theme.fontSizeMedium};
  43. padding-inline: 0;
  44. & > [data-property] {
  45. font-size: ${p => p.theme.fontSizeMedium};
  46. padding-inline: 0;
  47. }
  48. & > [data-node] {
  49. padding-left: ${space(2)};
  50. }
  51. `;