import { isPlainObject } from '@stoplight/json'; import { isRegularNode, RegularNode } from '@stoplight/json-schema-tree'; import { Box, Flex, HStack, Icon, Menu, Pressable } from '@stoplight/mosaic'; import { useUpdateAtom } from 'jotai/utils'; import { isEmpty } from 'lodash'; import * as React from 'react'; import { COMBINER_NAME_MAP } from '../../consts'; import { useJSVOptionsContext } from '../../contexts'; import { useIsOnScreen } from '../../hooks/useIsOnScreen'; import { isComplexArray, isDictionaryNode, visibleChildren } from '../../tree'; import { extractVendorExtensions } from '../../utils/extractVendorExtensions'; import { showPathCrumbsAtom } from '../PathCrumbs/state'; import { Description, getValidationsFromSchema, Validations } from '../shared'; import { ChildStack } from '../shared/ChildStack'; import { Error } from '../shared/Error'; import { SchemaRow, SchemaRowProps } from './SchemaRow'; import { useChoices } from './useChoices'; export const TopLevelSchemaRow = ({ schemaNode, skipDescription, }: Pick & { skipDescription?: boolean }) => { const { renderExtensionAddon } = useJSVOptionsContext(); const { selectedChoice, setSelectedChoice, choices } = useChoices(schemaNode); const childNodes = React.useMemo(() => visibleChildren(selectedChoice.type), [selectedChoice.type]); const nestingLevel = 0; const nodeId = (() => { if (isPlainObject(schemaNode.fragment) && isPlainObject(schemaNode.fragment['x-stoplight'])) { const id = schemaNode.fragment['x-stoplight'].id; return typeof id === 'string' ? id : undefined; } return undefined; })(); const [totalVendorExtensions, vendorExtensions] = React.useMemo( () => extractVendorExtensions(schemaNode.fragment), [schemaNode.fragment], ); const hasVendorProperties = totalVendorExtensions > 0; // regular objects are flattened at the top level if (isRegularNode(schemaNode) && isPureObjectNode(schemaNode)) { return ( <> {!skipDescription ? : null} {hasVendorProperties && renderExtensionAddon ? renderExtensionAddon({ schemaNode, nestingLevel, vendorExtensions }) : null} ); } if (isRegularNode(schemaNode) && choices.length > 1) { const combiner = isRegularNode(schemaNode) && schemaNode.combiners?.length ? schemaNode.combiners[0] : null; return ( <> {schemaNode.annotations.description !== schemaNode.parent?.fragment.description && ( )} ({ id: index, title: choice.title, onPress: () => setSelectedChoice(choice), }))} renderTrigger={props => ( {selectedChoice.title} )} /> {combiner !== null ? ( {`(${COMBINER_NAME_MAP[combiner]})`} ) : null} {childNodes.length > 0 ? ( ) : combiner ? ( ) : null} ); } if (isComplexArray(schemaNode) && isPureObjectNode(schemaNode.children[0])) { const validations = isRegularNode(schemaNode) ? getValidationsFromSchema(schemaNode) : {}; return ( <> array of: {!isEmpty(validations) && ( )} {childNodes.length > 0 ? ( ) : null} ); } return ( <> ); }; function ScrollCheck() { const elementRef = React.useRef(null); const isOnScreen = useIsOnScreen(elementRef); const setShowPathCrumbs = useUpdateAtom(showPathCrumbsAtom); React.useEffect(() => { setShowPathCrumbs(!isOnScreen); }, [isOnScreen, setShowPathCrumbs]); return
; } function isPureObjectNode(schemaNode: RegularNode) { return schemaNode.primaryType === 'object' && schemaNode.types?.length === 1 && !isDictionaryNode(schemaNode); }