Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/yellow-jobs-nail.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@gitbook/react-openapi': patch
'gitbook': patch
---

Improve OpenAPI circular references
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@

.openapi-schema,
.openapi-disclosure {
@apply py-2.5 flex flex-col gap-2;
@apply py-2.5 flex flex-col gap-2 scroll-mt-(--toc-top-offset);
}

.openapi-schema-properties .openapi-schema:last-child {
Expand Down Expand Up @@ -249,15 +249,15 @@
}

.openapi-schema-circular {
@apply text-xs text-tint;
@apply text-sm text-tint;
}

.openapi-schema-circular a {
@apply underline;
}

.openapi-schema-circular-glyph {
@apply text-base;
@apply text-base mr-1;
}

/* Schema Enum */
Expand Down
100 changes: 57 additions & 43 deletions packages/react-openapi/src/OpenAPISchema.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,13 @@ function OpenAPISchemaProperty(
const circularRefId = parentCircularRefs.get(schema);
// Avoid recursing infinitely, and instead render a link to the parent schema
if (circularRefId) {
return <OpenAPISchemaCircularRef id={circularRefId} schema={schema} />;
return (
<OpenAPISchemaPresentation
context={context}
property={property}
circularRefId={circularRefId}
/>
);
}

const circularRefs = new Map(parentCircularRefs);
Expand Down Expand Up @@ -99,15 +105,15 @@ function OpenAPISchemaProperty(

if (properties?.length) {
return (
<OpenAPIDisclosure
icon={context.icons.plus}
className={clsx('openapi-schema', className)}
header={header}
label={(isExpanded) => getDisclosureLabel({ schema, isExpanded, context })}
{...rest}
>
{content}
</OpenAPIDisclosure>
<div id={id} className={clsx('openapi-schema', className)} {...rest}>
<OpenAPIDisclosure
icon={context.icons.plus}
header={header}
label={(isExpanded) => getDisclosureLabel({ schema, isExpanded, context })}
>
{content}
</OpenAPIDisclosure>
</div>
);
}

Expand Down Expand Up @@ -289,8 +295,8 @@ function OpenAPISchemaCircularRef(props: { id: string; schema: OpenAPIV3.SchemaO

return (
<div className="openapi-schema-circular">
<span className="openapi-schema-circular-glyph">⤷</span>
Circular reference to <a href={`#${id}`}>{getSchemaTitle(schema)}</a>{' '}
<span className="openapi-schema-circular-glyph">↩</span>
</div>
);
}
Expand Down Expand Up @@ -361,9 +367,11 @@ function OpenAPISchemaEnum(props: {
export function OpenAPISchemaPresentation(props: {
property: OpenAPISchemaPropertyEntry;
context: OpenAPIClientContext;
circularRefId?: string;
}) {
const {
property: { schema, propertyName, required, isDiscriminatorProperty },
circularRefId,
context,
} = props;

Expand All @@ -380,38 +388,44 @@ export function OpenAPISchemaPresentation(props: {
required={required}
context={context}
/>
{typeof schema['x-deprecated-sunset'] === 'string' ? (
<div className="openapi-deprecated-sunset openapi-schema-description openapi-markdown">
Sunset date:{' '}
<span className="openapi-deprecated-sunset-date">
{schema['x-deprecated-sunset']}
</span>
</div>
) : null}
{description ? (
<Markdown source={description} className="openapi-schema-description" />
) : null}
{schema.default !== undefined ? (
<span className="openapi-schema-default">
Default:{' '}
<code>
{typeof schema.default === 'string' && schema.default
? schema.default
: stringifyOpenAPI(schema.default)}
</code>
</span>
) : null}
{typeof example === 'string' ? (
<span className="openapi-schema-example">
Example: <code>{example}</code>
</span>
) : null}
{schema.pattern ? (
<span className="openapi-schema-pattern">
Pattern: <code>{schema.pattern}</code>
</span>
) : null}
<OpenAPISchemaEnum schema={schema} context={context} />
{circularRefId ? (
<OpenAPISchemaCircularRef id={circularRefId} schema={schema} />
) : (
<>
{typeof schema['x-deprecated-sunset'] === 'string' ? (
<div className="openapi-deprecated-sunset openapi-schema-description openapi-markdown">
Sunset date:{' '}
<span className="openapi-deprecated-sunset-date">
{schema['x-deprecated-sunset']}
</span>
</div>
) : null}
{description ? (
<Markdown source={description} className="openapi-schema-description" />
) : null}
{schema.default !== undefined ? (
<span className="openapi-schema-default">
Default:{' '}
<code>
{typeof schema.default === 'string' && schema.default
? schema.default
: stringifyOpenAPI(schema.default)}
</code>
</span>
) : null}
{typeof example === 'string' ? (
<span className="openapi-schema-example">
Example: <code>{example}</code>
</span>
) : null}
{schema.pattern ? (
<span className="openapi-schema-pattern">
Pattern: <code>{schema.pattern}</code>
</span>
) : null}
<OpenAPISchemaEnum schema={schema} context={context} />
</>
)}
</div>
);
}
Expand Down
Loading