mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-12 05:48:57 +00:00
Support for x-enumDescriptions and x-gitbook-enum (#3066)
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
---
|
||||
'@gitbook/openapi-parser': patch
|
||||
'@gitbook/react-openapi': patch
|
||||
'gitbook': patch
|
||||
---
|
||||
|
||||
Support for x-enumDescriptions and x-gitbook-enum
|
||||
@@ -244,7 +244,11 @@
|
||||
|
||||
/* Schema Enum */
|
||||
.openapi-schema-enum {
|
||||
@apply flex flex-row text-sm leading-relaxed flex-wrap text-tint;
|
||||
@apply flex flex-row text-sm leading-relaxed gap-2 flex-wrap text-tint;
|
||||
}
|
||||
|
||||
.openapi-schema-enum-list {
|
||||
@apply flex flex-row gap-1.5 items-center;
|
||||
}
|
||||
|
||||
.openapi-schema-enum-value {
|
||||
@@ -693,3 +697,7 @@
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.openapi-copy-button {
|
||||
@apply hover:brightness-95;
|
||||
}
|
||||
|
||||
@@ -47,6 +47,21 @@ export interface OpenAPICustomOperationProperties {
|
||||
* Description in Document format.
|
||||
*/
|
||||
'x-gitbook-description-document'?: object;
|
||||
|
||||
/**
|
||||
* Enums with name and description
|
||||
*/
|
||||
'x-enumDescriptions'?: object;
|
||||
|
||||
/**
|
||||
* Enums with name and description
|
||||
*/
|
||||
'x-gitbook-enum'?: {
|
||||
[key: string]: {
|
||||
description?: string;
|
||||
name?: string;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,10 +6,16 @@ import { Button, type ButtonProps, Tooltip, TooltipTrigger } from 'react-aria-co
|
||||
export function OpenAPICopyButton(
|
||||
props: ButtonProps & {
|
||||
value: string;
|
||||
children: React.ReactNode;
|
||||
label?: string;
|
||||
/**
|
||||
* Whether to show a tooltip.
|
||||
* @default true
|
||||
*/
|
||||
withTooltip?: boolean;
|
||||
}
|
||||
) {
|
||||
const { value } = props;
|
||||
const { children, onPress, className } = props;
|
||||
const { value, label, children, onPress, className, withTooltip = true } = props;
|
||||
const [copied, setCopied] = useState(false);
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
@@ -21,12 +27,19 @@ export function OpenAPICopyButton(
|
||||
|
||||
setTimeout(() => {
|
||||
setCopied(false);
|
||||
setIsOpen(false);
|
||||
}, 2000);
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<TooltipTrigger isOpen={isOpen} onOpenChange={setIsOpen} closeDelay={200} delay={200}>
|
||||
<TooltipTrigger
|
||||
isOpen={isOpen}
|
||||
onOpenChange={setIsOpen}
|
||||
isDisabled={!withTooltip}
|
||||
closeDelay={200}
|
||||
delay={200}
|
||||
>
|
||||
<Button
|
||||
type="button"
|
||||
preventFocusOnPress
|
||||
@@ -47,7 +60,7 @@ export function OpenAPICopyButton(
|
||||
offset={4}
|
||||
className="openapi-tooltip"
|
||||
>
|
||||
{copied ? 'Copied' : 'Copy to clipboard'}{' '}
|
||||
{copied ? 'Copied' : label || 'Copy to clipboard'}
|
||||
</Tooltip>
|
||||
</TooltipTrigger>
|
||||
);
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
// This component does not use any client feature but we don't want to
|
||||
// render it server-side because it has recursion.
|
||||
|
||||
import type { OpenAPIV3 } from '@gitbook/openapi-parser';
|
||||
import type { OpenAPICustomOperationProperties, OpenAPIV3 } from '@gitbook/openapi-parser';
|
||||
import { useId } from 'react';
|
||||
|
||||
import clsx from 'clsx';
|
||||
import { Markdown } from './Markdown';
|
||||
import { OpenAPICopyButton } from './OpenAPICopyButton';
|
||||
import { OpenAPIDisclosure } from './OpenAPIDisclosure';
|
||||
import { OpenAPISchemaName } from './OpenAPISchemaName';
|
||||
import { retrocycle } from './decycle';
|
||||
@@ -236,20 +237,59 @@ function OpenAPISchemaCircularRef(props: { id: string; schema: OpenAPIV3.SchemaO
|
||||
/**
|
||||
* Render the enum value for a schema.
|
||||
*/
|
||||
function OpenAPISchemaEnum(props: { enumValues: any[] }) {
|
||||
const { enumValues } = props;
|
||||
function OpenAPISchemaEnum(props: {
|
||||
schema: OpenAPIV3.SchemaObject & OpenAPICustomOperationProperties;
|
||||
}) {
|
||||
const { schema } = props;
|
||||
|
||||
const enumValues = (() => {
|
||||
// Render x-gitbook-enum first, as it has a different format
|
||||
if (schema['x-gitbook-enum']) {
|
||||
return Object.entries(schema['x-gitbook-enum']).map(([name, { description }]) => {
|
||||
return {
|
||||
value: name,
|
||||
description,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
if (schema['x-enumDescriptions']) {
|
||||
return Object.entries(schema['x-enumDescriptions']).map(([value, description]) => {
|
||||
return {
|
||||
value,
|
||||
description,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
return schema.enum?.map((value) => {
|
||||
return {
|
||||
value,
|
||||
description: undefined,
|
||||
};
|
||||
});
|
||||
})();
|
||||
|
||||
if (!enumValues?.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="openapi-schema-enum">
|
||||
<span>
|
||||
Options:{' '}
|
||||
{enumValues.map((value, index) => (
|
||||
<span>Available options:</span>
|
||||
<div className="openapi-schema-enum-list">
|
||||
{enumValues.map((item, index) => (
|
||||
<span key={index} className="openapi-schema-enum-value">
|
||||
<code>{`${value}`}</code>
|
||||
{index < enumValues.length - 1 ? ', ' : ''}
|
||||
<OpenAPICopyButton
|
||||
value={item.value}
|
||||
label={item.description}
|
||||
withTooltip={!!item.description}
|
||||
>
|
||||
<code>{`${item.value}`}</code>
|
||||
</OpenAPICopyButton>
|
||||
</span>
|
||||
))}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -294,9 +334,7 @@ function OpenAPISchemaPresentation(props: { property: OpenAPISchemaPropertyEntry
|
||||
Pattern: <code>{schema.pattern}</code>
|
||||
</div>
|
||||
) : null}
|
||||
{schema.enum && schema.enum.length > 0 ? (
|
||||
<OpenAPISchemaEnum enumValues={schema.enum} />
|
||||
) : null}
|
||||
<OpenAPISchemaEnum schema={schema} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -421,7 +459,7 @@ function getSchemaTitle(schema: OpenAPIV3.SchemaObject): string {
|
||||
// Otherwise try to infer a nice title
|
||||
let type = 'any';
|
||||
|
||||
if (schema.enum) {
|
||||
if (schema.enum || schema['x-enumDescriptions'] || schema['x-gitbook-enum']) {
|
||||
type = `${schema.type} · enum`;
|
||||
// check array AND schema.items as this is sometimes null despite what the type indicates
|
||||
} else if (schema.type === 'array' && !!schema.items) {
|
||||
|
||||
Reference in New Issue
Block a user