diff --git a/src/core/plugins/json-schema-2020-12/components/JSONSchema/JSONSchema.jsx b/src/core/plugins/json-schema-2020-12/components/JSONSchema/JSONSchema.jsx index e23395c7..eca28ea1 100644 --- a/src/core/plugins/json-schema-2020-12/components/JSONSchema/JSONSchema.jsx +++ b/src/core/plugins/json-schema-2020-12/components/JSONSchema/JSONSchema.jsx @@ -49,6 +49,7 @@ const JSONSchema = ({ schema, name }) => { const KeywordThen = useComponent("KeywordThen") const KeywordElse = useComponent("KeywordElse") const KeywordDependentSchemas = useComponent("KeywordDependentSchemas") + const KeywordPrefixItems = useComponent("KeywordPrefixItems") const KeywordProperties = useComponent("KeywordProperties") const KeywordType = useComponent("KeywordType") const KeywordFormat = useComponent("KeywordFormat") @@ -121,6 +122,7 @@ const JSONSchema = ({ schema, name }) => { + diff --git a/src/core/plugins/json-schema-2020-12/components/keywords/PrefixItems.jsx b/src/core/plugins/json-schema-2020-12/components/keywords/PrefixItems.jsx new file mode 100644 index 00000000..47ed17bd --- /dev/null +++ b/src/core/plugins/json-schema-2020-12/components/keywords/PrefixItems.jsx @@ -0,0 +1,68 @@ +/** + * @prettier + */ +import React, { useCallback, useState } from "react" + +import { schema } from "../../prop-types" +import { useFn, 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 isExpandedDeeply = useIsExpandedDeeply() + const [expanded, setExpanded] = useState(isExpandedDeeply) + const [expandedDeeply, setExpandedDeeply] = useState(false) + const Accordion = useComponent("Accordion") + const ExpandDeepButton = useComponent("ExpandDeepButton") + const JSONSchema = useComponent("JSONSchema") + const KeywordType = useComponent("KeywordType") + + /** + * Event handlers. + */ + const handleExpansion = useCallback(() => { + setExpanded((prev) => !prev) + }, []) + const handleExpansionDeep = useCallback((e, expandedDeepNew) => { + setExpanded(expandedDeepNew) + setExpandedDeeply(expandedDeepNew) + }, []) + + return ( + +
+ + + Prefix items + + + + + {expanded && ( +
    + {prefixItems.map((schema, index) => ( +
  • + +
  • + ))} +
+ )} +
+
+ ) +} + +PrefixItems.propTypes = { + schema: schema.isRequired, +} + +export default PrefixItems diff --git a/src/core/plugins/json-schema-2020-12/fn.js b/src/core/plugins/json-schema-2020-12/fn.js index 58b2212a..98be04eb 100644 --- a/src/core/plugins/json-schema-2020-12/fn.js +++ b/src/core/plugins/json-schema-2020-12/fn.js @@ -34,18 +34,25 @@ export const getType = (schema, processedSchemas = new WeakSet()) => { } processedSchemas.add(schema) - const { type, items } = schema + const { type, prefixItems, items } = schema const getArrayType = () => { - if (!items) { + if (prefixItems) { + const prefixItemsTypes = prefixItems.map((itemSchema) => + getType(itemSchema, processedSchemas) + ) + const itemsType = items ? getType(items, processedSchemas) : "any" + return `array<[${prefixItemsTypes.join(", ")}], ${itemsType}>` + } else if (items) { + const itemsType = getType(items, processedSchemas) + return `array<${itemsType}>` + } else { return "array" } - const itemsType = getType(items, processedSchemas) - return `array<${itemsType}>` } const inferType = () => { - if (items) { + if (prefixItems || items) { return getArrayType() } else if (schema.properties || schema.additionalProperties) { return "object" @@ -134,6 +141,7 @@ export const isExpandable = (schema) => { schema?.then || schema?.else || schema?.dependentSchemas || + schema?.prefixItems || schema?.description || schema?.properties ) diff --git a/src/core/plugins/json-schema-2020-12/hoc.jsx b/src/core/plugins/json-schema-2020-12/hoc.jsx index d65a8c63..16ef1ad4 100644 --- a/src/core/plugins/json-schema-2020-12/hoc.jsx +++ b/src/core/plugins/json-schema-2020-12/hoc.jsx @@ -21,6 +21,7 @@ import KeywordIf from "./components/keywords/If" import KeywordThen from "./components/keywords/Then" import KeywordElse from "./components/keywords/Else" import KeywordDependentSchemas from "./components/keywords/DependentSchemas" +import KeywordPrefixItems from "./components/keywords/PrefixItems" import KeywordProperties from "./components/keywords/Properties/Properties" import KeywordType from "./components/keywords/Type/Type" import KeywordFormat from "./components/keywords/Format/Format" @@ -59,6 +60,7 @@ export const withJSONSchemaContext = (Component, overrides = {}) => { KeywordThen, KeywordElse, KeywordDependentSchemas, + KeywordPrefixItems, KeywordProperties, KeywordType, KeywordFormat, diff --git a/src/core/plugins/json-schema-2020-12/index.js b/src/core/plugins/json-schema-2020-12/index.js index 8358c4af..81f6110c 100644 --- a/src/core/plugins/json-schema-2020-12/index.js +++ b/src/core/plugins/json-schema-2020-12/index.js @@ -20,6 +20,7 @@ import KeywordIf from "./components/keywords/If" import KeywordThen from "./components/keywords/Then" import KeywordElse from "./components/keywords/Else" import KeywordDependentSchemas from "./components/keywords/DependentSchemas" +import KeywordPrefixItems from "./components/keywords/PrefixItems" import KeywordType from "./components/keywords/Type/Type" import KeywordFormat from "./components/keywords/Format/Format" import KeywordTitle from "./components/keywords/Title/Title" @@ -50,6 +51,7 @@ const JSONSchema202012Plugin = () => ({ JSONSchema202012KeywordThen: KeywordThen, JSONSchema202012KeywordElse: KeywordElse, JSONSchema202012KeywordDependentSchemas: KeywordDependentSchemas, + JSONSchema202012KeywordPrefixItems: KeywordPrefixItems, JSONSchema202012KeywordProperties: KeywordProperties, JSONSchema202012KeywordType: KeywordType, JSONSchema202012KeywordFormat: KeywordFormat, diff --git a/src/core/plugins/oas31/wrap-components/models.jsx b/src/core/plugins/oas31/wrap-components/models.jsx index 1304c11e..a674d709 100644 --- a/src/core/plugins/oas31/wrap-components/models.jsx +++ b/src/core/plugins/oas31/wrap-components/models.jsx @@ -30,6 +30,7 @@ const ModelsWrapper = createOnlyOAS31ComponentWrapper(({ getSystem }) => { const KeywordDependentSchemas = getComponent( "JSONSchema202012KeywordDependentSchemas" ) + const KeywordPrefixItems = getComponent("JSONSchema202012KeywordPrefixItems") const KeywordProperties = getComponent("JSONSchema202012KeywordProperties") const KeywordType = getComponent("JSONSchema202012KeywordType") const KeywordFormat = getComponent("JSONSchema202012KeywordFormat") @@ -66,6 +67,7 @@ const ModelsWrapper = createOnlyOAS31ComponentWrapper(({ getSystem }) => { KeywordThen, KeywordElse, KeywordDependentSchemas, + KeywordPrefixItems, KeywordProperties, KeywordType, KeywordFormat,