@@ -2,24 +2,17 @@ import { TreeStore } from '@stoplight/tree-list';
22import { Omit } from '@stoplight/types' ;
33import { runInAction } from 'mobx' ;
44import * as React from 'react' ;
5+ import ErrorBoundary , { ErrorBoundaryProps , FallbackProps } from 'react-error-boundary' ;
56
67import { isSchemaViewerEmpty , renderSchema } from '../utils' ;
78import { ISchemaTree , SchemaTree } from './SchemaTree' ;
89
9- export interface IJsonSchemaViewer extends Omit < ISchemaTree , 'treeStore' > {
10+ export interface IJsonSchemaViewer extends ErrorBoundaryProps , Omit < ISchemaTree , 'treeStore' > {
1011 emptyText ?: string ;
1112 defaultExpandedDepth ?: number ;
1213}
1314
14- export interface IJsonSchemaViewerState {
15- error : null | string ;
16- }
17-
18- export class JsonSchemaViewer extends React . PureComponent < IJsonSchemaViewer , IJsonSchemaViewerState > {
19- public state = {
20- error : null ,
21- } ;
22-
15+ class JsonSchemaViewerComponent extends React . PureComponent < IJsonSchemaViewer > {
2316 protected treeStore : TreeStore ;
2417
2518 constructor ( props : IJsonSchemaViewer ) {
@@ -31,11 +24,6 @@ export class JsonSchemaViewer extends React.PureComponent<IJsonSchemaViewer, IJs
3124 } ) ;
3225 }
3326
34- // there is no error hook yet, see https://reactjs.org/docs/hooks-faq.html#how-do-lifecycle-methods-correspond-to-hooks
35- public static getDerivedStateFromError ( error : Error ) : { error : IJsonSchemaViewerState [ 'error' ] } {
36- return { error : `Error rendering schema. ${ error . message } ` } ;
37- }
38-
3927 protected get expandedDepth ( ) : number {
4028 if ( this . props . expanded ) {
4129 return 2 ** 31 - 3 ; // tree-list kind of equivalent of expanded: all
@@ -67,13 +55,8 @@ export class JsonSchemaViewer extends React.PureComponent<IJsonSchemaViewer, IJs
6755 public render ( ) {
6856 const {
6957 props : { emptyText = 'No schema defined' , name, schema, expanded, defaultExpandedDepth, ...props } ,
70- state : { error } ,
7158 } = this ;
7259
73- if ( error ) {
74- return < div > { error } </ div > ;
75- }
76-
7760 // an empty array or object is still a valid response, schema is ONLY really empty when a combiner type has no information
7861 if ( isSchemaViewerEmpty ( schema ) ) {
7962 return < div > { emptyText } </ div > ;
@@ -82,3 +65,25 @@ export class JsonSchemaViewer extends React.PureComponent<IJsonSchemaViewer, IJs
8265 return < SchemaTree expanded = { expanded } name = { name } schema = { schema } treeStore = { this . treeStore } { ...props } /> ;
8366 }
8467}
68+
69+ const JsonSchemaFallbackComponent : React . FunctionComponent < FallbackProps > = ( { error } ) => {
70+ return (
71+ < div className = "p-4" >
72+ < b > Error</ b >
73+ { error && `: ${ error . message } ` }
74+ </ div >
75+ ) ;
76+ } ;
77+
78+ export const JsonSchemaViewer : React . FunctionComponent < IJsonSchemaViewer > = ( {
79+ onError,
80+ FallbackComponent = JsonSchemaFallbackComponent ,
81+ ...props
82+ } ) => {
83+ return (
84+ < ErrorBoundary onError = { onError } FallbackComponent = { FallbackComponent } >
85+ < JsonSchemaViewerComponent { ...props } />
86+ </ ErrorBoundary >
87+ ) ;
88+ } ;
89+ JsonSchemaViewer . displayName = 'JsonSchemaViewer' ;
0 commit comments