From 9ed1c1b3a0c2b48cf9898836522a141ecf456584 Mon Sep 17 00:00:00 2001 From: Vladimir Gorej Date: Thu, 13 Apr 2023 17:43:19 +0200 Subject: [PATCH] feat: introduce new UI + extendable behavior Ref #8513 --- .../components/Accordion/Accordion.jsx | 45 +++++++++ .../components/Accordion/_accordion.scss | 35 +++++++ .../components/JSONSchema/JSONSchema.jsx | 81 ++++++++++++++-- .../components/JSONSchema/_json-schema.scss | 92 +++++++++++++++++++ .../json-schema-2020-12/components/_all.scss | 1 + .../components/icons/ChevronRight.jsx | 17 ++++ src/core/plugins/json-schema-2020-12/hoc.jsx | 4 + src/core/plugins/json-schema-2020-12/index.js | 4 + .../plugins/oas31/wrap-components/models.jsx | 4 + src/style/main.scss | 2 +- 10 files changed, 277 insertions(+), 8 deletions(-) create mode 100644 src/core/plugins/json-schema-2020-12/components/Accordion/Accordion.jsx create mode 100644 src/core/plugins/json-schema-2020-12/components/Accordion/_accordion.scss create mode 100644 src/core/plugins/json-schema-2020-12/components/icons/ChevronRight.jsx diff --git a/src/core/plugins/json-schema-2020-12/components/Accordion/Accordion.jsx b/src/core/plugins/json-schema-2020-12/components/Accordion/Accordion.jsx new file mode 100644 index 00000000..175dd9ab --- /dev/null +++ b/src/core/plugins/json-schema-2020-12/components/Accordion/Accordion.jsx @@ -0,0 +1,45 @@ +/** + * @prettier + */ +import React, { useCallback } from "react" +import PropTypes from "prop-types" +import classNames from "classnames" + +import { useComponent } from "../../hooks" + +const Accordion = ({ expanded, children, onChange }) => { + const ChevronRightIcon = useComponent("ChevronRightIcon") + + const handleExpansion = useCallback( + (event) => { + onChange(event, !expanded) + }, + [expanded, onChange] + ) + + return ( + + ) +} + +Accordion.propTypes = { + expanded: PropTypes.bool, + children: PropTypes.node.isRequired, + onClick: PropTypes.func.isRequired, +} + +Accordion.defaultProps = { + expanded: false, +} + +export default Accordion diff --git a/src/core/plugins/json-schema-2020-12/components/Accordion/_accordion.scss b/src/core/plugins/json-schema-2020-12/components/Accordion/_accordion.scss new file mode 100644 index 00000000..98b5fbf5 --- /dev/null +++ b/src/core/plugins/json-schema-2020-12/components/Accordion/_accordion.scss @@ -0,0 +1,35 @@ +.json-schema-2020-12-accordion { + outline: none; + border: none; + display: flex; + align-items: center; + + &__children { + display: inline-block; + } + + &__icon { + width: 20px; + height: 20px; + display: inline-block; + vertical-align: center; + + &--expanded { + transition: transform .15s ease-in; + transform: rotate(-90deg); + transform-origin: 50% 50%; + } + + &--collapsed { + transition: transform .15s ease-in; + transform: rotate(0deg); + transform-origin: 50% 50%; + } + + & svg { + height: 20px; + width: 20px; + } + } +} + 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 727d3284..57042871 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 @@ -1,30 +1,97 @@ /** * @prettier */ -import React from "react" +import React, { useState, useCallback } 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 [expanded, setExpanded] = useState(false) + const fn = useFn() const BooleanJSONSchema = useComponent("BooleanJSONSchema") + const Accordion = useComponent("Accordion") + + const handleExpansion = useCallback(() => { + setExpanded((prev) => !prev) + }, []) if (fn.isBooleanJSONSchema(schema)) { return } return ( -
-
-
-
+
+
+ +
{name || fn.getTitle(schema)}
-
+
+ {expanded && ( +
+
+
+
+ property1 + Object + int64 + [0...100] +
+ Whether to turn on or off the light. +
+
+
+
+
+
+ + property11 + + Object +
+
+
+
+
+
+ + property22 + + Object +
+
+
+
+ Additional properties are allowed. +
+
+
+
+
+
+
+ property2 + Object +
+
+
+
+
+
+ property3 + Object +
+
+
+
+ Additional properties are allowed. +
+
+ )}
) } diff --git a/src/core/plugins/json-schema-2020-12/components/JSONSchema/_json-schema.scss b/src/core/plugins/json-schema-2020-12/components/JSONSchema/_json-schema.scss index e69de29b..50b14085 100644 --- a/src/core/plugins/json-schema-2020-12/components/JSONSchema/_json-schema.scss +++ b/src/core/plugins/json-schema-2020-12/components/JSONSchema/_json-schema.scss @@ -0,0 +1,92 @@ +.json-schema-2020-12 { + margin: 0 20px 15px 20px; + border-radius: 4px; + padding: 12px 0 12px 20px; + background-color: rgba($section-models-model-container-background-color, .05); + + &:first-of-type { + margin: 20px; + } + + &:last-of-type { + margin: 0 20px; + } + + &--embedded { + background-color: inherit; + padding: 0 inherit 0 inherit; + } + + &__title { + @include text_headline($section-models-model-title-font-color); + font-weight: bold; + } + + &-body { + margin: 2px 0; + border-left: 1px dashed rgba($section-models-model-container-background-color, 0.1); + } + + &-property { + margin: 7px 0; + + .json-schema-2020-12__title { + font-size: 12px; + @include text_code(); + } + } + + &__type { + @include text_code(); + color: $prop-type-font-color; + font-size: 12px; + text-transform: capitalize; + font-weight: bold; + margin-left: 10px; + + &:before { + content: "{"; + } + &:after { + content: "}"; + } + } + + &__description { + color: #6b6b6b; + font-size: 12px; + } + + &__format { + @include text_code(); + margin-left: 10px; + line-height: 1.5; + padding: 1px; + color: white; + background-color: #D69E2E; + border-radius: 4px; + + &:before { + content: "format: "; + } + } + + &__limit { + @include text_code(); + margin-left: 10px; + line-height: 1.5; + padding: 1px; + color: white; + background-color: #805AD5; + border-radius: 4px; + } + + &-note { + @include text_headline($section-models-model-title-font-color); + padding: 10px 0 0 20px; + font-size: 11px; + color: #6b6b6b; + } +} + + diff --git a/src/core/plugins/json-schema-2020-12/components/_all.scss b/src/core/plugins/json-schema-2020-12/components/_all.scss index 6cf4bd6f..33380233 100644 --- a/src/core/plugins/json-schema-2020-12/components/_all.scss +++ b/src/core/plugins/json-schema-2020-12/components/_all.scss @@ -1,2 +1,3 @@ @import './BooleanJSONSchema/boolean-json-schema'; @import './JSONSchema/json-schema'; +@import './Accordion/accordion'; diff --git a/src/core/plugins/json-schema-2020-12/components/icons/ChevronRight.jsx b/src/core/plugins/json-schema-2020-12/components/icons/ChevronRight.jsx new file mode 100644 index 00000000..e91c90fa --- /dev/null +++ b/src/core/plugins/json-schema-2020-12/components/icons/ChevronRight.jsx @@ -0,0 +1,17 @@ +/** + * @prettier + */ +import React from "react" + +const ChevronRight = () => ( + + + +) + +export default ChevronRight diff --git a/src/core/plugins/json-schema-2020-12/hoc.jsx b/src/core/plugins/json-schema-2020-12/hoc.jsx index 55853afc..8d288e1c 100644 --- a/src/core/plugins/json-schema-2020-12/hoc.jsx +++ b/src/core/plugins/json-schema-2020-12/hoc.jsx @@ -5,6 +5,8 @@ import React from "react" import JSONSchema from "./components/JSONSchema/JSONSchema" import BooleanJSONSchema from "./components/BooleanJSONSchema/BooleanJSONSchema" +import Accordion from "./components/Accordion/Accordion" +import ChevronRightIcon from "./components/icons/ChevronRight" import JSONSchemaContext from "./context" import { getTitle, isBooleanJSONSchema, upperFirst } from "./fn" @@ -13,6 +15,8 @@ export const withJSONSchemaContext = (Component, overrides = {}) => { components: { JSONSchema, BooleanJSONSchema, + Accordion, + ChevronRightIcon, ...overrides.components, }, config: { diff --git a/src/core/plugins/json-schema-2020-12/index.js b/src/core/plugins/json-schema-2020-12/index.js index 4ab3b30d..b76542d3 100644 --- a/src/core/plugins/json-schema-2020-12/index.js +++ b/src/core/plugins/json-schema-2020-12/index.js @@ -3,6 +3,8 @@ */ import JSONSchema from "./components/JSONSchema/JSONSchema" import BooleanJSONSchema from "./components/BooleanJSONSchema/BooleanJSONSchema" +import Accordion from "./components/Accordion/Accordion" +import ChevronRightIcon from "./components/icons/ChevronRight" import { upperFirst } from "./fn" import { withJSONSchemaContext } from "./hoc" @@ -10,6 +12,8 @@ const JSONSchema202012Plugin = () => ({ components: { JSONSchema202012: JSONSchema, BooleanJSONSchema202012: BooleanJSONSchema, + JSONSchema202012Accordion: Accordion, + JSONSchema202012ChevronRightIcon: ChevronRightIcon, withJSONSchema202012Context: withJSONSchemaContext, }, fn: { diff --git a/src/core/plugins/oas31/wrap-components/models.jsx b/src/core/plugins/oas31/wrap-components/models.jsx index 517f2464..84abe5c1 100644 --- a/src/core/plugins/oas31/wrap-components/models.jsx +++ b/src/core/plugins/oas31/wrap-components/models.jsx @@ -10,6 +10,8 @@ const ModelsWrapper = createOnlyOAS31ComponentWrapper(({ getSystem }) => { const Models = getComponent("OAS31Models", true) const JSONSchema = getComponent("JSONSchema202012") const BooleanJSONSchema = getComponent("BooleanJSONSchema202012") + const Accordion = getComponent("JSONSchema202012Accordion") + const ChevronRightIcon = getComponent("JSONSchema202012ChevronRightIcon") const withSchemaContext = getComponent("withJSONSchema202012Context") const ModelsWithJSONContext = withSchemaContext(Models, { config: { @@ -18,6 +20,8 @@ const ModelsWrapper = createOnlyOAS31ComponentWrapper(({ getSystem }) => { components: { JSONSchema, BooleanJSONSchema, + Accordion, + ChevronRightIcon, }, fn: { upperFirst: fn.upperFirst, diff --git a/src/style/main.scss b/src/style/main.scss index 9decf300..758eec28 100644 --- a/src/style/main.scss +++ b/src/style/main.scss @@ -15,8 +15,8 @@ @import 'information'; @import 'authorize'; @import 'errors'; - @import '../core/plugins/json-schema-2020-12/components/all'; @include text_body(); @import 'split-pane-mode'; @import 'markdown'; + @import '../core/plugins/json-schema-2020-12/components/all'; }