From f5ab5d8b9f9816346e88d7cb0edc077df4b801e9 Mon Sep 17 00:00:00 2001 From: Domagoj Kriskovic Date: Fri, 16 Jul 2021 13:30:01 +0200 Subject: [PATCH 1/3] feat: added onTreePopulated prop --- src/components/JsonSchemaViewer.tsx | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/components/JsonSchemaViewer.tsx b/src/components/JsonSchemaViewer.tsx index 126a68be..77000dde 100644 --- a/src/components/JsonSchemaViewer.tsx +++ b/src/components/JsonSchemaViewer.tsx @@ -1,4 +1,5 @@ import { isRegularNode, SchemaTree as JsonSchemaTree, SchemaTreeRefDereferenceFn } from '@stoplight/json-schema-tree'; +import type { WalkerEmitter, WalkerNodeEventHandler } from '@stoplight/json-schema-tree/walker'; import { Box, Provider as MosaicProvider } from '@stoplight/mosaic'; import { ErrorBoundaryForwardedProps, FallbackProps, withErrorBoundary } from '@stoplight/react-error-boundary'; import cn from 'classnames'; @@ -14,6 +15,11 @@ export type JsonSchemaProps = Partial & { emptyText?: string; className?: string; resolveRef?: SchemaTreeRefDereferenceFn; + treeWalkerEventEmitter?: { + event: keyof WalkerEmitter; + handler: WalkerNodeEventHandler; + }; + onTreePopulated?: (tree: JsonSchemaTree) => void; }; const JsonSchemaViewerComponent: React.FC = ({ @@ -26,12 +32,19 @@ const JsonSchemaViewerComponent: React.FC { const jsonSchemaTreeRoot = React.useMemo(() => { const jsonSchemaTree = new JsonSchemaTree(schema, { mergeAllOf: true, refResolver: resolveRef, }); + + if (treeWalkerEventEmitter) { + jsonSchemaTree.walker.on(treeWalkerEventEmitter.event, treeWalkerEventEmitter.handler); + } + jsonSchemaTree.walker.hookInto('filter', node => { if (!isRegularNode(node)) return true; @@ -44,8 +57,9 @@ const JsonSchemaViewerComponent: React.FC jsonSchemaTreeRoot.children.every(node => !isRegularNode(node) || node.unknown), [ jsonSchemaTreeRoot, From 8af359d9fe601cfffb44a2ccd5f905eb630a39c3 Mon Sep 17 00:00:00 2001 From: Domagoj Kriskovic Date: Fri, 16 Jul 2021 17:27:03 +0200 Subject: [PATCH 2/3] fix: removed treeWalkerEventEmitter --- src/components/JsonSchemaViewer.tsx | 46 ++++++++++++++++++----------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/src/components/JsonSchemaViewer.tsx b/src/components/JsonSchemaViewer.tsx index 77000dde..45bad0f6 100644 --- a/src/components/JsonSchemaViewer.tsx +++ b/src/components/JsonSchemaViewer.tsx @@ -1,5 +1,10 @@ -import { isRegularNode, SchemaTree as JsonSchemaTree, SchemaTreeRefDereferenceFn } from '@stoplight/json-schema-tree'; -import type { WalkerEmitter, WalkerNodeEventHandler } from '@stoplight/json-schema-tree/walker'; +import { + isRegularNode, + RootNode, + SchemaNode, + SchemaTree as JsonSchemaTree, + SchemaTreeRefDereferenceFn, +} from '@stoplight/json-schema-tree'; import { Box, Provider as MosaicProvider } from '@stoplight/mosaic'; import { ErrorBoundaryForwardedProps, FallbackProps, withErrorBoundary } from '@stoplight/react-error-boundary'; import cn from 'classnames'; @@ -15,11 +20,7 @@ export type JsonSchemaProps = Partial & { emptyText?: string; className?: string; resolveRef?: SchemaTreeRefDereferenceFn; - treeWalkerEventEmitter?: { - event: keyof WalkerEmitter; - handler: WalkerNodeEventHandler; - }; - onTreePopulated?: (tree: JsonSchemaTree) => void; + onTreePopulated?: (rootNode: RootNode, nodeCount: number) => void; }; const JsonSchemaViewerComponent: React.FC = ({ @@ -32,20 +33,16 @@ const JsonSchemaViewerComponent: React.FC { - const jsonSchemaTreeRoot = React.useMemo(() => { + const { jsonSchemaTreeRoot, nodeCount } = React.useMemo(() => { const jsonSchemaTree = new JsonSchemaTree(schema, { mergeAllOf: true, refResolver: resolveRef, }); - if (treeWalkerEventEmitter) { - jsonSchemaTree.walker.on(treeWalkerEventEmitter.event, treeWalkerEventEmitter.handler); - } - - jsonSchemaTree.walker.hookInto('filter', node => { + let nodeCount = 0; + const shouldNodeBeIncluded = (node: SchemaNode) => { if (!isRegularNode(node)) return true; const { validations } = node; @@ -55,11 +52,22 @@ const JsonSchemaViewerComponent: React.FC { + if (shouldNodeBeIncluded(node)) { + nodeCount++; + return true; + } + return false; }); jsonSchemaTree.populate(); - onTreePopulated?.(jsonSchemaTree); - return jsonSchemaTree.root; - }, [schema, resolveRef, viewMode, treeWalkerEventEmitter, onTreePopulated]); + + return { + jsonSchemaTreeRoot: jsonSchemaTree.root, + nodeCount, + }; + }, [schema, resolveRef, viewMode]); const isEmpty = React.useMemo(() => jsonSchemaTreeRoot.children.every(node => !isRegularNode(node) || node.unknown), [ jsonSchemaTreeRoot, @@ -73,6 +81,10 @@ const JsonSchemaViewerComponent: React.FC { + onTreePopulated?.(jsonSchemaTreeRoot, nodeCount); + }, [jsonSchemaTreeRoot, onTreePopulated, nodeCount]); + if (isEmpty) { return {emptyText}; } From cdf750950093913b78f16b2222ea4277e37fccf6 Mon Sep 17 00:00:00 2001 From: Domagoj Kriskovic Date: Fri, 16 Jul 2021 17:34:21 +0200 Subject: [PATCH 3/3] chore: use props object --- src/components/JsonSchemaViewer.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/components/JsonSchemaViewer.tsx b/src/components/JsonSchemaViewer.tsx index 45bad0f6..f31fd94e 100644 --- a/src/components/JsonSchemaViewer.tsx +++ b/src/components/JsonSchemaViewer.tsx @@ -20,7 +20,7 @@ export type JsonSchemaProps = Partial & { emptyText?: string; className?: string; resolveRef?: SchemaTreeRefDereferenceFn; - onTreePopulated?: (rootNode: RootNode, nodeCount: number) => void; + onTreePopulated?: (props: { rootNode: RootNode; nodeCount: number }) => void; }; const JsonSchemaViewerComponent: React.FC = ({ @@ -82,7 +82,10 @@ const JsonSchemaViewerComponent: React.FC { - onTreePopulated?.(jsonSchemaTreeRoot, nodeCount); + onTreePopulated?.({ + rootNode: jsonSchemaTreeRoot, + nodeCount: nodeCount, + }); }, [jsonSchemaTreeRoot, onTreePopulated, nodeCount]); if (isEmpty) {