feat(json-schema-2020-12): add initial rendering engine

Refs #8513
This commit is contained in:
Vladimir Gorej
2023-04-12 17:09:35 +02:00
committed by Vladimír Gorej
parent dbd8931161
commit ab1842083d
17 changed files with 311 additions and 1 deletions

View File

@@ -0,0 +1,27 @@
/**
* @prettier
*/
import React from "react"
import PropTypes from "prop-types"
import { booleanSchema } from "../../prop-types"
const BooleanJSONSchema = ({ schema, name }) => {
return (
<article className="json-schema-2020-12 json-schema-2020-12--boolean">
<span>{name}</span>
<span>{schema ? "true" : "false"}</span>
</article>
)
}
BooleanJSONSchema.propTypes = {
schema: booleanSchema.isRequired,
name: PropTypes.string,
}
BooleanJSONSchema.defaultProps = {
name: "",
}
export default BooleanJSONSchema

View File

@@ -0,0 +1,41 @@
/**
* @prettier
*/
import React from "react"
import PropTypes from "prop-types"
import * as propTypes from "../../prop-types"
import { useComponent, useFn } from "../../hooks"
const JSONSchema = ({ schema, name }) => {
const fn = useFn()
const BooleanJSONSchema = useComponent("BooleanJSONSchema")
if (fn.isBooleanJSONSchema(schema)) {
return <BooleanJSONSchema schema={schema} name={name} />
}
return (
<article className="json-schema-2020-12 model-container">
<div className="model-box">
<div className="model">
<div className="json-schema-2020-12__title model-title">
{name || fn.getTitle(schema)}
</div>
</div>
</div>
</article>
)
}
JSONSchema.propTypes = {
name: PropTypes.string,
schema: propTypes.schema.isRequired,
}
JSONSchema.defaultProps = {
name: "",
}
export default JSONSchema

View File

@@ -0,0 +1,2 @@
@import './BooleanJSONSchema/boolean-json-schema';
@import './JSONSchema/json-schema';

View File

@@ -0,0 +1,9 @@
/**
* @prettier
*/
import { createContext } from "react"
export const JSONSchemaContext = createContext(null)
JSONSchemaContext.displayName = "JSONSchemaContext"
export default JSONSchemaContext

View File

@@ -0,0 +1,20 @@
/**
* @prettier
*/
export const upperFirst = (value) => {
if (typeof value === "string") {
return `${value.charAt(0).toUpperCase()}${value.slice(1)}`
}
return value
}
export const getTitle = (schema) => {
if (schema.title) return upperFirst(schema.title)
if (schema.$anchor) return upperFirst(schema.$anchor)
if (schema.$id) return schema.$id
return ""
}
export const isBooleanJSONSchema = (schema) => typeof schema === "boolean"

View File

@@ -0,0 +1,41 @@
/**
* @prettier
*/
import React from "react"
import JSONSchema from "./components/JSONSchema/JSONSchema"
import BooleanJSONSchema from "./components/BooleanJSONSchema/BooleanJSONSchema"
import JSONSchemaContext from "./context"
import { getTitle, isBooleanJSONSchema, upperFirst } from "./fn"
export const withJSONSchemaContext = (Component, overrides = {}) => {
const value = {
components: {
JSONSchema,
BooleanJSONSchema,
...overrides.components,
},
config: {
default$schema: "https://json-schema.org/draft/2020-12/schema",
...overrides.config,
},
fn: {
upperFirst,
getTitle,
isBooleanJSONSchema,
...overrides.fn,
},
}
const HOC = (props) => (
<JSONSchemaContext.Provider value={value}>
<Component {...props} />
</JSONSchemaContext.Provider>
)
HOC.contexts = {
JSONSchemaContext,
}
HOC.displayName = Component.displayName
return HOC
}

View File

@@ -0,0 +1,22 @@
/**
* @prettier
*/
import { useContext } from "react"
import JSONSchemaContext from "./context"
export const useConfig = () => {
const { config } = useContext(JSONSchemaContext)
return config
}
export const useComponent = (componentName) => {
const { components } = useContext(JSONSchemaContext)
return components[componentName] || null
}
export const useFn = (fnName = undefined) => {
const { fn } = useContext(JSONSchemaContext)
return typeof fnName !== "undefined" ? fn[fnName] : fn
}

View File

@@ -0,0 +1,20 @@
/**
* @prettier
*/
import JSONSchema from "./components/JSONSchema/JSONSchema"
import BooleanJSONSchema from "./components/BooleanJSONSchema/BooleanJSONSchema"
import { upperFirst } from "./fn"
import { withJSONSchemaContext } from "./hoc"
const JSONSchema202012Plugin = () => ({
components: {
JSONSchema202012: JSONSchema,
BooleanJSONSchema202012: BooleanJSONSchema,
withJSONSchema202012Context: withJSONSchemaContext,
},
fn: {
upperFirst,
},
})
export default JSONSchema202012Plugin

View File

@@ -0,0 +1,10 @@
/**
* @prettier
*/
import PropTypes from "prop-types"
export const objectSchema = PropTypes.object
export const booleanSchema = PropTypes.bool
export const schema = PropTypes.oneOfType([objectSchema, booleanSchema])