feat(json-schema-2020-12): add support for defaultExpandedLevels opt

optimizeExpansion config option was introduced as well
to support rendering extensive or very complex schemas.

Refs #8513
This commit is contained in:
Vladimir Gorej
2023-04-25 14:27:31 +02:00
committed by Vladimír Gorej
parent fa829e3368
commit 7c15f509b7
26 changed files with 343 additions and 174 deletions

View File

@@ -9,6 +9,7 @@ import * as propTypes from "../../prop-types"
import {
useComponent,
useLevel,
useConfig,
useFn,
useIsEmbedded,
useIsExpandedDeeply,
@@ -23,6 +24,7 @@ import {
const JSONSchema = forwardRef(({ schema, name }, ref) => {
const fn = useFn()
const config = useConfig()
const isExpandedDeeply = useIsExpandedDeeply()
const [expanded, setExpanded] = useState(isExpandedDeeply)
const [expandedDeeply, setExpandedDeeply] = useState(false)
@@ -120,43 +122,49 @@ const JSONSchema = forwardRef(({ schema, name }, ref) => {
<KeywordType schema={schema} isCircular={isCircular} />
<KeywordFormat schema={schema} />
</div>
{expanded && (
<div className="json-schema-2020-12-body">
<KeywordDescription schema={schema} />
{!isCircular && isExpandable && (
<>
<KeywordProperties schema={schema} />
<KeywordPatternProperties schema={schema} />
<KeywordAdditionalProperties schema={schema} />
<KeywordUnevaluatedProperties schema={schema} />
<KeywordPropertyNames schema={schema} />
<KeywordAllOf schema={schema} />
<KeywordAnyOf schema={schema} />
<KeywordOneOf schema={schema} />
<KeywordNot schema={schema} />
<KeywordIf schema={schema} />
<KeywordThen schema={schema} />
<KeywordElse schema={schema} />
<KeywordDependentSchemas schema={schema} />
<KeywordPrefixItems schema={schema} />
<KeywordItems schema={schema} />
<KeywordUnevaluatedItems schema={schema} />
<KeywordContains schema={schema} />
</>
)}
<Keyword$schema schema={schema} />
<Keyword$vocabulary schema={schema} />
<Keyword$id schema={schema} />
<Keyword$anchor schema={schema} />
<Keyword$dynamicAnchor schema={schema} />
<Keyword$ref schema={schema} />
{!isCircular && isExpandable && (
<Keyword$defs schema={schema} />
)}
<Keyword$dynamicRef schema={schema} />
<Keyword$comment schema={schema} />
</div>
)}
<div
className={classNames("json-schema-2020-12-body", {
"json-schema-2020-12-body--collapsed": !expanded,
})}
>
{!expanded && config.optimizeExpansion ? null : (
<>
<KeywordDescription schema={schema} />
{!isCircular && isExpandable && (
<>
<KeywordProperties schema={schema} />
<KeywordPatternProperties schema={schema} />
<KeywordAdditionalProperties schema={schema} />
<KeywordUnevaluatedProperties schema={schema} />
<KeywordPropertyNames schema={schema} />
<KeywordAllOf schema={schema} />
<KeywordAnyOf schema={schema} />
<KeywordOneOf schema={schema} />
<KeywordNot schema={schema} />
<KeywordIf schema={schema} />
<KeywordThen schema={schema} />
<KeywordElse schema={schema} />
<KeywordDependentSchemas schema={schema} />
<KeywordPrefixItems schema={schema} />
<KeywordItems schema={schema} />
<KeywordUnevaluatedItems schema={schema} />
<KeywordContains schema={schema} />
</>
)}
<Keyword$schema schema={schema} />
<Keyword$vocabulary schema={schema} />
<Keyword$id schema={schema} />
<Keyword$anchor schema={schema} />
<Keyword$dynamicAnchor schema={schema} />
<Keyword$ref schema={schema} />
{!isCircular && isExpandable && (
<Keyword$defs schema={schema} />
)}
<Keyword$dynamicRef schema={schema} />
<Keyword$comment schema={schema} />
</>
)}
</div>
</article>
</JSONSchemaCyclesContext.Provider>
</JSONSchemaDeepExpansionContext.Provider>

View File

@@ -20,6 +20,10 @@
&-body {
@include expansion-border;
margin: 2px 0;
&--collapsed {
display: none;
}
}
&__limit {

View File

@@ -2,18 +2,15 @@
* @prettier
*/
import React, { useCallback, useState } from "react"
import classNames from "classnames"
import { schema } from "../../prop-types"
import { useComponent, useIsExpandedDeeply } from "../../hooks"
import { useConfig, useComponent, useIsExpandedDeeply } from "../../hooks"
import { JSONSchemaDeepExpansionContext } from "../../context"
const $defs = ({ schema }) => {
const $defs = schema?.$defs || {}
if (Object.keys($defs).length === 0) {
return null
}
const config = useConfig()
const isExpandedDeeply = useIsExpandedDeeply()
const [expanded, setExpanded] = useState(isExpandedDeeply)
const [expandedDeeply, setExpandedDeeply] = useState(false)
@@ -32,6 +29,13 @@ const $defs = ({ schema }) => {
setExpandedDeeply(expandedDeepNew)
}, [])
/**
* Rendering.
*/
if (Object.keys($defs).length === 0) {
return null
}
return (
<JSONSchemaDeepExpansionContext.Provider value={expandedDeeply}>
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--$defs">
@@ -42,15 +46,21 @@ const $defs = ({ schema }) => {
</Accordion>
<ExpandDeepButton expanded={expanded} onClick={handleExpansionDeep} />
<span className="json-schema-2020-12__type">object</span>
{expanded && (
<ul>
{Object.entries($defs).map(([schemaName, schema]) => (
<li key={schemaName} className="json-schema-2020-12-property">
<JSONSchema name={schemaName} schema={schema} />
</li>
))}
</ul>
)}
<ul
className={classNames("json-schema-2020-12-keyword__children", {
"json-schema-2020-12-keyword__children--collapsed": !expanded,
})}
>
{!expanded && config.optimizeExpansion ? null : (
<>
{Object.entries($defs).map(([schemaName, schema]) => (
<li key={schemaName} className="json-schema-2020-12-property">
<JSONSchema name={schemaName} schema={schema} />
</li>
))}
</>
)}
</ul>
</div>
</JSONSchemaDeepExpansionContext.Provider>
)

View File

@@ -8,9 +8,6 @@ import { schema } from "../../../prop-types"
import { useComponent, useIsExpandedDeeply } from "../../../hooks"
const $vocabulary = ({ schema }) => {
if (!schema?.$vocabulary) return null
if (typeof schema.$vocabulary !== "object") return null
const isExpandedDeeply = useIsExpandedDeeply()
const [expanded, setExpanded] = useState(isExpandedDeeply)
const Accordion = useComponent("Accordion")
@@ -19,6 +16,12 @@ const $vocabulary = ({ schema }) => {
setExpanded((prev) => !prev)
}, [])
/**
* Rendering.
*/
if (!schema?.$vocabulary) return null
if (typeof schema.$vocabulary !== "object") return null
return (
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--$vocabulary">
<Accordion expanded={expanded} onChange={handleExpansion}>

View File

@@ -8,11 +8,14 @@ import { useFn, useComponent } from "../../hooks"
const AdditionalProperties = ({ schema }) => {
const fn = useFn()
const { additionalProperties } = schema
const JSONSchema = useComponent("JSONSchema")
if (!fn.hasKeyword(schema, "additionalProperties")) return null
const { additionalProperties } = schema
const JSONSchema = useComponent("JSONSchema")
/**
* Rendering.
*/
const name = (
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary">
Additional properties

View File

@@ -2,19 +2,21 @@
* @prettier
*/
import React, { useCallback, useState } from "react"
import classNames from "classnames"
import { schema } from "../../prop-types"
import { useFn, useComponent, useIsExpandedDeeply } from "../../hooks"
import {
useFn,
useConfig,
useComponent,
useIsExpandedDeeply,
} from "../../hooks"
import { JSONSchemaDeepExpansionContext } from "../../context"
const AllOf = ({ schema }) => {
const allOf = schema?.allOf || []
if (!Array.isArray(allOf) || allOf.length === 0) {
return null
}
const fn = useFn()
const config = useConfig()
const isExpandedDeeply = useIsExpandedDeeply()
const [expanded, setExpanded] = useState(isExpandedDeeply)
const [expandedDeeply, setExpandedDeeply] = useState(false)
@@ -34,6 +36,13 @@ const AllOf = ({ schema }) => {
setExpandedDeeply(expandedDeepNew)
}, [])
/**
* Rendering.
*/
if (!Array.isArray(allOf) || allOf.length === 0) {
return null
}
return (
<JSONSchemaDeepExpansionContext.Provider value={expandedDeeply}>
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--allOf">
@@ -44,18 +53,24 @@ const AllOf = ({ schema }) => {
</Accordion>
<ExpandDeepButton expanded={expanded} onClick={handleExpansionDeep} />
<KeywordType schema={{ allOf }} />
{expanded && (
<ul>
{allOf.map((schema, index) => (
<li key={`#${index}`} className="json-schema-2020-12-property">
<JSONSchema
name={`#${index} ${fn.getTitle(schema)}`}
schema={schema}
/>
</li>
))}
</ul>
)}
<ul
className={classNames("json-schema-2020-12-keyword__children", {
"json-schema-2020-12-keyword__children--collapsed": !expanded,
})}
>
{!expanded && config.optimizeExpansion ? null : (
<>
{allOf.map((schema, index) => (
<li key={`#${index}`} className="json-schema-2020-12-property">
<JSONSchema
name={`#${index} ${fn.getTitle(schema)}`}
schema={schema}
/>
</li>
))}
</>
)}
</ul>
</div>
</JSONSchemaDeepExpansionContext.Provider>
)

View File

@@ -2,19 +2,21 @@
* @prettier
*/
import React, { useCallback, useState } from "react"
import classNames from "classnames"
import { schema } from "../../prop-types"
import { useFn, useComponent, useIsExpandedDeeply } from "../../hooks"
import {
useFn,
useConfig,
useComponent,
useIsExpandedDeeply,
} from "../../hooks"
import { JSONSchemaDeepExpansionContext } from "../../context"
const AnyOf = ({ schema }) => {
const anyOf = schema?.anyOf || []
if (!Array.isArray(anyOf) || anyOf.length === 0) {
return null
}
const fn = useFn()
const config = useConfig()
const isExpandedDeeply = useIsExpandedDeeply()
const [expanded, setExpanded] = useState(isExpandedDeeply)
const [expandedDeeply, setExpandedDeeply] = useState(false)
@@ -34,6 +36,13 @@ const AnyOf = ({ schema }) => {
setExpandedDeeply(expandedDeepNew)
}, [])
/**
* Rendering.
*/
if (!Array.isArray(anyOf) || anyOf.length === 0) {
return null
}
return (
<JSONSchemaDeepExpansionContext.Provider value={expandedDeeply}>
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--anyOf">
@@ -44,18 +53,24 @@ const AnyOf = ({ schema }) => {
</Accordion>
<ExpandDeepButton expanded={expanded} onClick={handleExpansionDeep} />
<KeywordType schema={{ anyOf }} />
{expanded && (
<ul>
{anyOf.map((schema, index) => (
<li key={`#${index}`} className="json-schema-2020-12-property">
<JSONSchema
name={`#${index} ${fn.getTitle(schema)}`}
schema={schema}
/>
</li>
))}
</ul>
)}
<ul
className={classNames("json-schema-2020-12-keyword__children", {
"json-schema-2020-12-keyword__children--collapsed": !expanded,
})}
>
{!expanded && config.optimizeExpansion ? null : (
<>
{anyOf.map((schema, index) => (
<li key={`#${index}`} className="json-schema-2020-12-property">
<JSONSchema
name={`#${index} ${fn.getTitle(schema)}`}
schema={schema}
/>
</li>
))}
</>
)}
</ul>
</div>
</JSONSchemaDeepExpansionContext.Provider>
)

View File

@@ -8,9 +8,6 @@ import { useFn, useComponent } from "../../hooks"
const Contains = ({ schema }) => {
const fn = useFn()
if (!fn.hasKeyword(schema, "contains")) return null
const JSONSchema = useComponent("JSONSchema")
const name = (
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary">
@@ -18,6 +15,11 @@ const Contains = ({ schema }) => {
</span>
)
/**
* Rendering.
*/
if (!fn.hasKeyword(schema, "contains")) return null
return (
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--contains">
<JSONSchema name={name} schema={schema.contains} />

View File

@@ -2,17 +2,15 @@
* @prettier
*/
import React, { useCallback, useState } from "react"
import classNames from "classnames"
import { schema } from "../../prop-types"
import { useComponent, useIsExpandedDeeply } from "../../hooks"
import { useConfig, useComponent, useIsExpandedDeeply } from "../../hooks"
import { JSONSchemaDeepExpansionContext } from "../../context"
const DependentSchemas = ({ schema }) => {
const dependentSchemas = schema?.dependentSchemas || []
if (typeof dependentSchemas !== "object") return null
if (Object.keys(dependentSchemas).length === 0) return null
const config = useConfig()
const isExpandedDeeply = useIsExpandedDeeply()
const [expanded, setExpanded] = useState(isExpandedDeeply)
const [expandedDeeply, setExpandedDeeply] = useState(false)
@@ -31,6 +29,12 @@ const DependentSchemas = ({ schema }) => {
setExpandedDeeply(expandedDeepNew)
}, [])
/**
* Rendering.
*/
if (typeof dependentSchemas !== "object") return null
if (Object.keys(dependentSchemas).length === 0) return null
return (
<JSONSchemaDeepExpansionContext.Provider value={expandedDeeply}>
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--dependentSchemas">
@@ -41,15 +45,21 @@ const DependentSchemas = ({ schema }) => {
</Accordion>
<ExpandDeepButton expanded={expanded} onClick={handleExpansionDeep} />
<span className="json-schema-2020-12__type">object</span>
{expanded && (
<ul>
{Object.entries(dependentSchemas).map(([schemaName, schema]) => (
<li key={schemaName} className="json-schema-2020-12-property">
<JSONSchema name={schemaName} schema={schema} />
</li>
))}
</ul>
)}
<ul
className={classNames("json-schema-2020-12-keyword__children", {
"json-schema-2020-12-keyword__children--collapsed": !expanded,
})}
>
{!expanded && config.optimizeExpansion ? null : (
<>
{Object.entries(dependentSchemas).map(([schemaName, schema]) => (
<li key={schemaName} className="json-schema-2020-12-property">
<JSONSchema name={schemaName} schema={schema} />
</li>
))}
</>
)}
</ul>
</div>
</JSONSchemaDeepExpansionContext.Provider>
)

View File

@@ -8,10 +8,13 @@ import { useFn, useComponent } from "../../hooks"
const Else = ({ schema }) => {
const fn = useFn()
const JSONSchema = useComponent("JSONSchema")
/**
* Rendering.
*/
if (!fn.hasKeyword(schema, "else")) return null
const JSONSchema = useComponent("JSONSchema")
const name = (
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary">
Else

View File

@@ -8,10 +8,13 @@ import { useFn, useComponent } from "../../hooks"
const If = ({ schema }) => {
const fn = useFn()
const JSONSchema = useComponent("JSONSchema")
/**
* Rendering.
*/
if (!fn.hasKeyword(schema, "if")) return null
const JSONSchema = useComponent("JSONSchema")
const name = (
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary">
If

View File

@@ -7,9 +7,13 @@ import { schema } from "../../prop-types"
import { useComponent } from "../../hooks"
const Items = ({ schema }) => {
const JSONSchema = useComponent("JSONSchema")
/**
* Rendering.
*/
if (!schema?.items) return null
const JSONSchema = useComponent("JSONSchema")
const name = (
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary">
Items

View File

@@ -8,10 +8,13 @@ import { useFn, useComponent } from "../../hooks"
const Not = ({ schema }) => {
const fn = useFn()
const JSONSchema = useComponent("JSONSchema")
/**
* Rendering.
*/
if (!fn.hasKeyword(schema, "not")) return null
const JSONSchema = useComponent("JSONSchema")
const name = (
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary">
Not

View File

@@ -2,19 +2,21 @@
* @prettier
*/
import React, { useCallback, useState } from "react"
import classNames from "classnames"
import { schema } from "../../prop-types"
import { useFn, useComponent, useIsExpandedDeeply } from "../../hooks"
import {
useFn,
useConfig,
useComponent,
useIsExpandedDeeply,
} from "../../hooks"
import { JSONSchemaDeepExpansionContext } from "../../context"
const OneOf = ({ schema }) => {
const oneOf = schema?.oneOf || []
if (!Array.isArray(oneOf) || oneOf.length === 0) {
return null
}
const fn = useFn()
const config = useConfig()
const isExpandedDeeply = useIsExpandedDeeply()
const [expanded, setExpanded] = useState(isExpandedDeeply)
const [expandedDeeply, setExpandedDeeply] = useState(false)
@@ -34,6 +36,13 @@ const OneOf = ({ schema }) => {
setExpandedDeeply(expandedDeepNew)
}, [])
/**
* Rendering.
*/
if (!Array.isArray(oneOf) || oneOf.length === 0) {
return null
}
return (
<JSONSchemaDeepExpansionContext.Provider value={expandedDeeply}>
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--oneOf">
@@ -44,18 +53,24 @@ const OneOf = ({ schema }) => {
</Accordion>
<ExpandDeepButton expanded={expanded} onClick={handleExpansionDeep} />
<KeywordType schema={{ oneOf }} />
{expanded && (
<ul>
{oneOf.map((schema, index) => (
<li key={`#${index}`} className="json-schema-2020-12-property">
<JSONSchema
name={`#${index} ${fn.getTitle(schema)}`}
schema={schema}
/>
</li>
))}
</ul>
)}
<ul
className={classNames("json-schema-2020-12-keyword__children", {
"json-schema-2020-12-keyword__children--collapsed": !expanded,
})}
>
{!expanded && config.optimizeExpansion ? null : (
<>
{oneOf.map((schema, index) => (
<li key={`#${index}`} className="json-schema-2020-12-property">
<JSONSchema
name={`#${index} ${fn.getTitle(schema)}`}
schema={schema}
/>
</li>
))}
</>
)}
</ul>
</div>
</JSONSchemaDeepExpansionContext.Provider>
)

View File

@@ -8,13 +8,15 @@ import { useComponent } from "../../../hooks"
const PatternProperties = ({ schema }) => {
const patternProperties = schema?.patternProperties || {}
const JSONSchema = useComponent("JSONSchema")
/**
* Rendering.
*/
if (Object.keys(patternProperties).length === 0) {
return null
}
const JSONSchema = useComponent("JSONSchema")
return (
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--patternProperties">
<ul>

View File

@@ -2,19 +2,21 @@
* @prettier
*/
import React, { useCallback, useState } from "react"
import classNames from "classnames"
import { schema } from "../../prop-types"
import { useFn, useComponent, useIsExpandedDeeply } from "../../hooks"
import {
useFn,
useConfig,
useComponent,
useIsExpandedDeeply,
} from "../../hooks"
import { JSONSchemaDeepExpansionContext } from "../../context"
const PrefixItems = ({ schema }) => {
const prefixItems = schema?.prefixItems || []
if (!Array.isArray(prefixItems) || prefixItems.length === 0) {
return null
}
const fn = useFn()
const config = useConfig()
const isExpandedDeeply = useIsExpandedDeeply()
const [expanded, setExpanded] = useState(isExpandedDeeply)
const [expandedDeeply, setExpandedDeeply] = useState(false)
@@ -34,6 +36,13 @@ const PrefixItems = ({ schema }) => {
setExpandedDeeply(expandedDeepNew)
}, [])
/**
* Rendering.
*/
if (!Array.isArray(prefixItems) || prefixItems.length === 0) {
return null
}
return (
<JSONSchemaDeepExpansionContext.Provider value={expandedDeeply}>
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--prefixItems">
@@ -44,18 +53,24 @@ const PrefixItems = ({ schema }) => {
</Accordion>
<ExpandDeepButton expanded={expanded} onClick={handleExpansionDeep} />
<KeywordType schema={{ prefixItems }} />
{expanded && (
<ul>
{prefixItems.map((schema, index) => (
<li key={`#${index}`} className="json-schema-2020-12-property">
<JSONSchema
name={`#${index} ${fn.getTitle(schema)}`}
schema={schema}
/>
</li>
))}
</ul>
)}
<ul
className={classNames("json-schema-2020-12-keyword__children", {
"json-schema-2020-12-keyword__children--collapsed": !expanded,
})}
>
{!expanded && config.optimizeExpansion ? null : (
<>
{prefixItems.map((schema, index) => (
<li key={`#${index}`} className="json-schema-2020-12-property">
<JSONSchema
name={`#${index} ${fn.getTitle(schema)}`}
schema={schema}
/>
</li>
))}
</>
)}
</ul>
</div>
</JSONSchemaDeepExpansionContext.Provider>
)

View File

@@ -8,13 +8,15 @@ import { useComponent } from "../../../hooks"
const Properties = ({ schema }) => {
const properties = schema?.properties || {}
const JSONSchema = useComponent("JSONSchema")
/**
* Rendering.
*/
if (Object.keys(properties).length === 0) {
return null
}
const JSONSchema = useComponent("JSONSchema")
return (
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--properties">
<ul>

View File

@@ -8,9 +8,6 @@ import { useFn, useComponent } from "../../hooks"
const PropertyNames = ({ schema }) => {
const fn = useFn()
if (!fn.hasKeyword(schema, "propertyNames")) return null
const { propertyNames } = schema
const JSONSchema = useComponent("JSONSchema")
const name = (
@@ -19,6 +16,11 @@ const PropertyNames = ({ schema }) => {
</span>
)
/**
* Rendering.
*/
if (!fn.hasKeyword(schema, "propertyNames")) return null
return (
<div className="json-schema-2020-12-keyword json-schema-2020-12-keyword--propertyNames">
<JSONSchema name={name} schema={propertyNames} />

View File

@@ -8,10 +8,13 @@ import { useFn, useComponent } from "../../hooks"
const Then = ({ schema }) => {
const fn = useFn()
const JSONSchema = useComponent("JSONSchema")
/**
* Rendering.
*/
if (!fn.hasKeyword(schema, "then")) return null
const JSONSchema = useComponent("JSONSchema")
const name = (
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary">
Then

View File

@@ -8,11 +8,14 @@ import { useFn, useComponent } from "../../hooks"
const UnevaluatedItems = ({ schema }) => {
const fn = useFn()
if (!fn.hasKeyword(schema, "unevaluatedItems")) return null
const { unevaluatedItems } = schema
const JSONSchema = useComponent("JSONSchema")
/**
* Rendering.
*/
if (!fn.hasKeyword(schema, "unevaluatedItems")) return null
const name = (
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary">
Unevaluated items

View File

@@ -8,11 +8,14 @@ import { useFn, useComponent } from "../../hooks"
const UnevaluatedProperties = ({ schema }) => {
const fn = useFn()
if (!fn.hasKeyword(schema, "unevaluatedProperties")) return null
const { unevaluatedProperties } = schema
const JSONSchema = useComponent("JSONSchema")
/**
* Rendering.
*/
if (!fn.hasKeyword(schema, "unevaluatedProperties")) return null
const name = (
<span className="json-schema-2020-12-keyword__name json-schema-2020-12-keyword__name--primary">
Unevaluated properties

View File

@@ -1,9 +1,13 @@
.json-schema-2020-12-keyword {
margin: 5px 0 5px 0;
& > ul {
&__children {
@include expansion-border;
padding: 0;
&--collapsed {
display: none;
}
}
&__name {

View File

@@ -88,6 +88,23 @@ export const withJSONSchemaContext = (Component, overrides = {}) => {
},
config: {
default$schema: "https://json-schema.org/draft/2020-12/schema",
/**
* Defines an upper exclusive boundary of the level range for automatic expansion.
*
* 0 -> do nothing
* 1 -> [0]...(1)
* 2 -> [0]...(2)
* 3 -> [0]...(3)
*/
defaultExpandedLevels: 0, // 2 = 0...2
/**
* Can be turned on for complex and extensive schemas.
* Child schemas are not rendered until parent schema is expanded.
*
* By default, entire schema tree is rendered and collapsed parts of the
* tree are hidden with css.
*/
optimizeExpansion: false,
...overrides.config,
},
fn: {

View File

@@ -39,7 +39,11 @@ export const useIsEmbedded = () => {
}
export const useIsExpandedDeeply = () => {
return useContext(JSONSchemaDeepExpansionContext)
const [level] = useLevel()
const { defaultExpandedLevels } = useConfig()
const isExpandedByDefault = defaultExpandedLevels - level > 0
return isExpandedByDefault || useContext(JSONSchemaDeepExpansionContext)
}
export const useRenderedSchemas = (schema = undefined) => {

View File

@@ -15,6 +15,7 @@ const Models = ({
fn,
}) => {
const schemas = specSelectors.selectSchemas()
const hasSchemas = Object.keys(schemas).length > 0
const schemasPath = ["components", "schemas"]
const { docExpansion, defaultModelsExpandDepth } = getConfigs()
const isOpenDefault = defaultModelsExpandDepth > 0 && docExpansion !== "none"
@@ -34,15 +35,19 @@ const Models = ({
/**
* Event handlers.
*/
const handleCollapse = useCallback(() => {
layoutActions.show(schemasPath, !isOpen)
}, [layoutActions, schemasPath, isOpen])
}, [isOpen, layoutActions])
const handleModelsRef = useCallback((node) => {
if (node !== null) {
layoutActions.readyToScroll(schemasPath, node)
}
}, [])
const handleModelsRef = useCallback(
(node) => {
if (node !== null) {
layoutActions.readyToScroll(schemasPath, node)
}
},
[layoutActions]
)
const handleJSONSchema202012Ref = (schemaName) => (node) => {
if (node !== null) {
@@ -50,6 +55,14 @@ const Models = ({
}
}
/**
* Rendering.
*/
if (!hasSchemas || defaultModelsExpandDepth < 0) {
return null
}
return (
<section
className={classNames("models", { "is-open": isOpen })}
@@ -86,6 +99,7 @@ Models.propTypes = {
getConfigs: PropTypes.func.isRequired,
specSelectors: PropTypes.shape({
selectSchemas: PropTypes.func.isRequired,
specResolvedSubtree: PropTypes.func.isRequired,
}).isRequired,
specActions: PropTypes.shape({
requestResolvedSubtree: PropTypes.func.isRequired,
@@ -95,6 +109,7 @@ Models.propTypes = {
}).isRequired,
layoutActions: PropTypes.shape({
show: PropTypes.func.isRequired,
readyToScroll: PropTypes.func.isRequired,
}).isRequired,
fn: PropTypes.shape({
upperFirst: PropTypes.func.isRequired,

View File

@@ -6,7 +6,8 @@ import React from "react"
import { createOnlyOAS31ComponentWrapper } from "../fn"
const ModelsWrapper = createOnlyOAS31ComponentWrapper(({ getSystem }) => {
const { getComponent, fn } = getSystem()
const { getComponent, fn, getConfigs } = getSystem()
const configs = getConfigs()
if (ModelsWrapper.ModelsWithJSONContext) {
return <ModelsWrapper.ModelsWithJSONContext />
@@ -61,7 +62,6 @@ const ModelsWrapper = createOnlyOAS31ComponentWrapper(({ getSystem }) => {
"JSONSchema202012KeywordDescription",
true
)
const Accordion = getComponent("JSONSchema202012Accordion")
const ExpandDeepButton = getComponent("JSONSchema202012ExpandDeepButton")
const ChevronRightIcon = getComponent("JSONSchema202012ChevronRightIcon")
@@ -70,6 +70,7 @@ const ModelsWrapper = createOnlyOAS31ComponentWrapper(({ getSystem }) => {
ModelsWrapper.ModelsWithJSONContext = withSchemaContext(Models, {
config: {
default$schema: "https://spec.openapis.org/oas/3.1/dialect/base",
defaultExpandedLevels: configs.defaultModelsExpandDepth - 1,
},
components: {
JSONSchema,