import styled from '@emotion/styled'; import { isNonEmptyString } from '@sniptt/guards'; import { IconComponent } from '@ui/display'; import { JsonArrow } from '@ui/json-visualizer/components/internal/JsonArrow'; import { JsonList } from '@ui/json-visualizer/components/internal/JsonList'; import { JsonNodeLabel } from '@ui/json-visualizer/components/internal/JsonNodeLabel'; import { JsonNodeValue } from '@ui/json-visualizer/components/internal/JsonNodeValue'; import { JsonNode } from '@ui/json-visualizer/components/JsonNode'; import { useJsonTreeContextOrThrow } from '@ui/json-visualizer/hooks/useJsonTreeContextOrThrow'; import { JsonNodeHighlighting } from '@ui/json-visualizer/types/JsonNodeHighlighting'; import { ANIMATION } from '@ui/theme'; import { AnimatePresence, motion } from 'framer-motion'; import { useState } from 'react'; import { isDefined } from 'twenty-shared/utils'; import { JsonValue } from 'type-fest'; const StyledContainer = styled.li` display: grid; list-style-type: none; `; const StyledLabelContainer = styled.div` display: flex; align-items: center; gap: ${({ theme }) => theme.spacing(2)}; `; const StyledElementsCount = styled.span` color: ${({ theme }) => theme.font.color.tertiary}; `; const StyledJsonList = styled(JsonList)``.withComponent(motion.ul); export const JsonNestedNode = ({ label, Icon, elements, renderElementsCount, emptyElementsText, depth, keyPath, highlighting, }: { label?: string; Icon: IconComponent; elements: Array<{ id: string | number; label: string; value: JsonValue }>; renderElementsCount?: (count: number) => string; emptyElementsText: string; depth: number; keyPath: string; highlighting?: JsonNodeHighlighting | undefined; }) => { const { shouldExpandNodeInitially } = useJsonTreeContextOrThrow(); const hideRoot = !isDefined(label); const [isOpen, setIsOpen] = useState( shouldExpandNodeInitially({ keyPath, depth }), ); const renderedChildren = ( {elements.length === 0 ? ( ) : ( elements.map(({ id, label, value }) => { const nextKeyPath = isNonEmptyString(keyPath) ? `${keyPath}.${id}` : String(id); return ( ); }) )} ); const handleArrowClick = () => { setIsOpen(!isOpen); }; if (hideRoot) { return ( {renderedChildren} ); } return ( {renderElementsCount && ( {renderElementsCount(elements.length)} )} {isOpen && renderedChildren} ); };