Skip to content

Commit

Permalink
feat(json-schema-2020-12): handle cycles in rendering
Browse files Browse the repository at this point in the history
Refs #8513
  • Loading branch information
char0n committed Apr 26, 2023
1 parent fe181ed commit 7d5cad0
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@ import {
useFn,
useIsEmbedded,
useIsExpandedDeeply,
useIsCircular,
useRenderedSchemas,
} from "../../hooks"
import {
JSONSchemaLevelContext,
JSONSchemaDeepExpansionContext,
JSONSchemaCyclesContext,
} from "../../context"

const JSONSchema = ({ schema, name }) => {
Expand All @@ -26,6 +29,8 @@ const JSONSchema = ({ schema, name }) => {
const [level, nextLevel] = useLevel()
const isEmbedded = useIsEmbedded()
const isExpandable = fn.isExpandable(schema)
const isCircular = useIsCircular(schema)
const renderedSchemas = useRenderedSchemas(schema)
const Accordion = useComponent("Accordion")
const KeywordProperties = useComponent("KeywordProperties")
const KeywordType = useComponent("KeywordType")
Expand Down Expand Up @@ -59,36 +64,41 @@ const JSONSchema = ({ schema, name }) => {
return (
<JSONSchemaLevelContext.Provider value={nextLevel}>
<JSONSchemaDeepExpansionContext.Provider value={expandedDeeply}>
<article
data-json-schema-level={level}
className={classNames("json-schema-2020-12", {
"json-schema-2020-12--embedded": isEmbedded,
})}
>
<div className="json-schema-2020-12-head">
{isExpandable ? (
<>
<Accordion expanded={expanded} onChange={handleExpansion}>
<KeywordTitle title={name} schema={schema} />
</Accordion>
<ExpandDeepButton
expanded={expanded}
onClick={handleExpansionDeep}
/>
</>
) : (
<KeywordTitle title={name} schema={schema} />
)}
<KeywordType schema={schema} />
<KeywordFormat schema={schema} />
</div>
{expanded && (
<div className="json-schema-2020-12-body">
<KeywordDescription schema={schema} />
<KeywordProperties schema={schema} />
<JSONSchemaCyclesContext.Provider value={renderedSchemas}>
<article
data-json-schema-level={level}
className={classNames("json-schema-2020-12", {
"json-schema-2020-12--embedded": isEmbedded,
"json-schema-2020-12--circular": isCircular,
})}
>
<div className="json-schema-2020-12-head">
{isExpandable && !isCircular ? (
<>
<Accordion expanded={expanded} onChange={handleExpansion}>
<KeywordTitle title={name} schema={schema} />
</Accordion>
<ExpandDeepButton
expanded={expanded}
onClick={handleExpansionDeep}
/>
</>
) : (
<KeywordTitle title={name} schema={schema} />
)}
<KeywordType schema={schema} isCircular={isCircular} />
<KeywordFormat schema={schema} />
</div>
)}
</article>
{expanded && (
<div className="json-schema-2020-12-body">
<KeywordDescription schema={schema} />
{!isCircular && isExpandable && (
<KeywordProperties schema={schema} />
)}
</div>
)}
</article>
</JSONSchemaCyclesContext.Provider>
</JSONSchemaDeepExpansionContext.Provider>
</JSONSchemaLevelContext.Provider>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,28 @@
* @prettier
*/
import React from "react"
import PropTypes from "prop-types"

import { schema } from "../../../prop-types"
import { useFn } from "../../../hooks"

const Type = ({ schema }) => {
const Type = ({ schema, isCircular }) => {
const fn = useFn()
const type = fn.getType(schema)
const circularSuffix = isCircular ? " [circular]" : ""

return <span className="json-schema-2020-12__type">{fn.getType(schema)}</span>
return (
<span className="json-schema-2020-12__type">{`${type}${circularSuffix}`}</span>
)
}

Type.propTypes = {
schema: schema.isRequired,
isCircular: PropTypes.bool,
}

Type.defaultProps = {
isCircular: false,
}

export default Type
2 changes: 2 additions & 0 deletions src/core/plugins/json-schema-2020-12/context.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@ JSONSchemaLevelContext.displayName = "JSONSchemaLevelContext"

export const JSONSchemaDeepExpansionContext = createContext(false)
JSONSchemaDeepExpansionContext.displayName = "JSONSchemaDeepExpansionContext"

export const JSONSchemaCyclesContext = createContext(new Set())
14 changes: 14 additions & 0 deletions src/core/plugins/json-schema-2020-12/hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
JSONSchemaContext,
JSONSchemaLevelContext,
JSONSchemaDeepExpansionContext,
JSONSchemaCyclesContext,
} from "./context"

export const useConfig = () => {
Expand Down Expand Up @@ -40,3 +41,16 @@ export const useIsEmbedded = () => {
export const useIsExpandedDeeply = () => {
return useContext(JSONSchemaDeepExpansionContext)
}

export const useRenderedSchemas = (schema = undefined) => {
if (typeof schema === "undefined") {
return useContext(JSONSchemaCyclesContext)
}

const renderedSchemas = useContext(JSONSchemaCyclesContext)
return new Set([...renderedSchemas, schema])
}
export const useIsCircular = (schema) => {
const renderedSchemas = useRenderedSchemas()
return renderedSchemas.has(schema)
}

0 comments on commit 7d5cad0

Please sign in to comment.