TextNode.tsx 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import React from "react";
  2. import { MdCompareArrows } from "react-icons/md";
  3. import { useInViewport } from "react-in-viewport";
  4. import { CustomNodeProps } from "src/components/CustomNode";
  5. import useConfig from "src/hooks/store/useConfig";
  6. import useGraph from "src/hooks/store/useGraph";
  7. import useStored from "src/hooks/store/useStored";
  8. import styled from "styled-components";
  9. import * as Styled from "./styles";
  10. const StyledExpand = styled.button`
  11. pointer-events: all;
  12. position: absolute;
  13. display: flex;
  14. align-items: center;
  15. justify-content: center;
  16. top: 0;
  17. right: 0;
  18. padding: 0;
  19. color: ${({ theme }) => theme.TEXT_NORMAL};
  20. background: rgba(0, 0, 0, 0.1);
  21. min-height: 0;
  22. height: 100%;
  23. width: 40px;
  24. border-radius: 0;
  25. border-left: 1px solid ${({ theme }) => theme.BACKGROUND_MODIFIER_ACCENT};
  26. `;
  27. const TextNode: React.FC<
  28. CustomNodeProps<string> & { node: NodeData; hasCollapse: boolean }
  29. > = ({
  30. node,
  31. width,
  32. height,
  33. value,
  34. isParent = false,
  35. hasCollapse = false,
  36. x,
  37. y,
  38. }) => {
  39. const ref = React.useRef(null);
  40. const { inViewport } = useInViewport(ref);
  41. const performanceMode = useConfig((state) => state.performanceMode);
  42. const hideCollapse = useStored((state) => state.hideCollapse);
  43. const expandNodes = useGraph((state) => state.expandNodes);
  44. const collapseNodes = useGraph((state) => state.collapseNodes);
  45. const [isExpanded, setIsExpanded] = React.useState(true);
  46. const handleExpand = (e: React.MouseEvent<HTMLButtonElement>) => {
  47. e.stopPropagation();
  48. setIsExpanded(!isExpanded);
  49. if (isExpanded) collapseNodes(node.id);
  50. else expandNodes(node.id);
  51. };
  52. return (
  53. <Styled.StyledForeignObject
  54. width={width}
  55. height={height}
  56. x={0}
  57. y={0}
  58. data-nodeid={node.id}
  59. ref={ref}
  60. >
  61. {(!performanceMode || inViewport) && (
  62. <Styled.StyledTextWrapper>
  63. <Styled.StyledText
  64. hideCollapse={hideCollapse}
  65. hasCollapse={isParent && hasCollapse}
  66. width={width}
  67. height={height}
  68. >
  69. <Styled.StyledKey
  70. data-x={x}
  71. data-y={y}
  72. data-key={JSON.stringify(value)}
  73. parent={isParent}
  74. >
  75. <Styled.StyledLinkItUrl>
  76. {JSON.stringify(value).replaceAll('"', "")}
  77. </Styled.StyledLinkItUrl>
  78. </Styled.StyledKey>
  79. </Styled.StyledText>
  80. </Styled.StyledTextWrapper>
  81. )}
  82. {inViewport && isParent && hasCollapse && !hideCollapse && (
  83. <StyledExpand onClick={handleExpand}>
  84. <MdCompareArrows size={18} />
  85. </StyledExpand>
  86. )}
  87. </Styled.StyledForeignObject>
  88. );
  89. };
  90. export default TextNode;