mirror of
https://github.com/hanzo-docs/docs.git
synced 2026-10-25 04:20:02 +00:00
Feat/openapi server select (#1046)
Co-authored-by: Fuma Nama <[email protected]>
This commit is contained in:
co-authored by
Fuma Nama
parent
aa1f401cd3
commit
196b78b9cb
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'fumadocs-openapi': minor
|
||||
---
|
||||
|
||||
OpenAPI: Server selector to allow interacting with different API environments
|
||||
@@ -11,6 +11,7 @@ info:
|
||||
url: 'https://opensource.org/license/mit/'
|
||||
servers:
|
||||
- url: 'https://redocly.com/_mock/docs/openapi/museum-api'
|
||||
- url: 'https://example.com/api/v1'
|
||||
paths:
|
||||
/museum-hours:
|
||||
get:
|
||||
|
||||
+1133
-342
File diff suppressed because it is too large
Load Diff
@@ -33,11 +33,13 @@ interface CodeSampleCompiled {
|
||||
}
|
||||
|
||||
export function Operation({
|
||||
baseUrls,
|
||||
path,
|
||||
method,
|
||||
ctx,
|
||||
hasHead,
|
||||
}: {
|
||||
baseUrls: string[];
|
||||
path: string;
|
||||
method: MethodInformation;
|
||||
ctx: RenderContext;
|
||||
@@ -147,7 +149,11 @@ export function Operation({
|
||||
|
||||
return (
|
||||
<ctx.renderer.API>
|
||||
<ctx.renderer.APIInfo method={method.method} route={path}>
|
||||
<ctx.renderer.APIInfo
|
||||
method={method.method}
|
||||
route={path}
|
||||
baseUrls={baseUrls}
|
||||
>
|
||||
{info}
|
||||
</ctx.renderer.APIInfo>
|
||||
<APIExample method={method} endpoint={endpoint} ctx={ctx} />
|
||||
|
||||
@@ -27,6 +27,7 @@ export interface ResponseProps {
|
||||
export interface APIInfoProps {
|
||||
method: string;
|
||||
route: string;
|
||||
baseUrls: string[];
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
|
||||
@@ -62,6 +62,9 @@ export async function APIPage(props: ApiPageProps): Promise<ReactElement> {
|
||||
method={method}
|
||||
path={item.path}
|
||||
ctx={ctx}
|
||||
baseUrls={
|
||||
document.servers ? document.servers.map((s) => s.url) : []
|
||||
}
|
||||
hasHead={hasHead}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -74,4 +74,28 @@ export function CopyRouteButton({
|
||||
);
|
||||
}
|
||||
|
||||
export function BaseUrlSelect({ baseUrls }: { baseUrls: string[] }) {
|
||||
const { baseUrl, setBaseUrl } = useApiContext();
|
||||
if (baseUrls.length === 0) return null;
|
||||
|
||||
return (
|
||||
<div className="flex flex-row items-center gap-1 px-1">
|
||||
<span className="p-0.5 text-xs font-medium text-fd-muted-foreground">
|
||||
Server
|
||||
</span>
|
||||
<select
|
||||
value={baseUrl}
|
||||
onChange={(e) => setBaseUrl(e.target.value)}
|
||||
className="min-w-0 flex-1 bg-transparent font-mono text-xs text-fd-foreground outline-none"
|
||||
>
|
||||
{baseUrls.map((url) => (
|
||||
<option key={url} value={url}>
|
||||
{url}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export { useSchemaContext } from './contexts/schema';
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Fragment, type HTMLAttributes, type ReactNode } from 'react';
|
||||
import { Accordion, Accordions } from 'fumadocs-ui/components/accordion';
|
||||
import { badgeVariants, getBadgeColor } from '@/ui/components/variants';
|
||||
import type { APIInfoProps, PropertyProps } from '@/render/renderer';
|
||||
import { CopyRouteButton } from '@/ui/client';
|
||||
import { BaseUrlSelect, CopyRouteButton } from '@/ui/client';
|
||||
|
||||
export { Root, useSchemaContext, APIPlayground } from './client';
|
||||
|
||||
@@ -31,28 +31,30 @@ export function APIInfo({
|
||||
className,
|
||||
route,
|
||||
badgeClassname,
|
||||
baseUrls,
|
||||
method = 'GET',
|
||||
...props
|
||||
}: APIInfoProps &
|
||||
HTMLAttributes<HTMLDivElement> & {
|
||||
badgeClassname?: string;
|
||||
}): React.ReactElement {
|
||||
}) {
|
||||
return (
|
||||
<div className={cn('min-w-0 flex-1', className)} {...props}>
|
||||
<div className="sticky top-[var(--fd-api-info-top)] z-[4] mb-4 flex flex-row items-center gap-1.5 border-b border-fd-foreground/10 bg-fd-card/50 px-4 py-1.5 shadow-lg backdrop-blur-lg max-lg:-mx-3 max-md:-mx-4 md:rounded-full md:border md:px-1.5">
|
||||
<span
|
||||
className={cn(
|
||||
badgeVariants({ color: getBadgeColor(method) }),
|
||||
badgeClassname,
|
||||
)}
|
||||
>
|
||||
{method}
|
||||
</span>
|
||||
<Route route={route} />
|
||||
|
||||
<CopyRouteButton className="ms-auto size-6 p-1.5" route={route} />
|
||||
<div className="sticky top-[var(--fd-api-info-top)] z-[4] mb-4 border-b border-fd-foreground/10 bg-fd-card/50 px-4 py-1.5 shadow-lg backdrop-blur-lg max-lg:-mx-3 max-md:-mx-4 md:rounded-xl md:border md:px-1.5">
|
||||
<div className="mb-2 flex flex-row items-center gap-1.5">
|
||||
<span
|
||||
className={cn(
|
||||
badgeVariants({ color: getBadgeColor(method) }),
|
||||
badgeClassname,
|
||||
)}
|
||||
>
|
||||
{method}
|
||||
</span>
|
||||
<Route route={route} />
|
||||
<CopyRouteButton className="ms-auto size-6 p-1.5" route={route} />
|
||||
</div>
|
||||
<BaseUrlSelect baseUrls={baseUrls} />
|
||||
</div>
|
||||
|
||||
<div className="prose-no-margin">{children}</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -16,7 +16,6 @@ export function generateDocument(
|
||||
options: GenerateOptions & {
|
||||
dereferenced: OpenAPI.Document;
|
||||
page: ApiPageProps;
|
||||
|
||||
title: string;
|
||||
description?: string;
|
||||
context: DocumentContext;
|
||||
|
||||
Reference in New Issue
Block a user