Files
gitbook/src/components/DocumentView/OpenAPI/OpenAPI.tsx
T
Marc Laventure 4f039ecb2b feat: add scalar api client (#180)
* wip

* feat: add scalar api client

* fix: pr feedback

* feat: add scalar react client package, remove vueary

* feat: add scalar proxy

* Move dependencies to package

* Format once

* Rename prop

* Use react context and simplify lazy loading

* Add loading state

* Format

* Move styles

* bun install

* bun

* fix: remove extraneous api-reference package

* feat: make operation functional with spec in client

* fix: column bug and http request type wrapping

* fix: add scalar api reference package

* Format

* bun install

* fix: scrolling in scalar modal

* Lazy load operations data in component

* fix: change dependency from api-reference to oas-utils to reduce size

* bun install

* Log error in the worker proxy

* Cleanup

* Comment "mode"

* Without credentials and referrerPolicy

---------

Co-authored-by: Samy Pessé <samypesse@gmail.com>
Co-authored-by: Amrit <amrit@hockey-community.com>
2024-03-19 15:32:54 +01:00

88 lines
3.0 KiB
TypeScript

import { ChevronDown, ChevronRight } from '@geist-ui/icons';
import { DocumentBlockSwagger } from '@gitbook/api';
import React from 'react';
import { LoadingPane } from '@/components/primitives';
import { fetchOpenAPIBlock } from '@/lib/openapi';
import { tcls } from '@/lib/tailwind';
import { OpenAPIOperation } from '@gitbook/react-openapi';
import { BlockProps } from '../Block';
import { PlainCodeBlock } from '../CodeBlock';
import './style.css';
import './scalar.css';
/**
* Render an OpenAPI block.
*/
export async function OpenAPI(props: BlockProps<DocumentBlockSwagger>) {
const { block, style } = props;
return (
<div className={tcls('w-full', 'flex', 'flex-row', style, 'max-w-full')}>
{/*
Invisible span with the ID to correctly identify the active section in the aside navigation.
We don't use the full <div> because it can be longer than the viewport and will not work well with IntersectionObserver.
*/}
<span id={block.meta?.id} />
<React.Suspense fallback={<OpenAPIFallback />}>
<OpenAPIBody {...props} />
</React.Suspense>
</div>
);
}
async function OpenAPIBody(props: BlockProps<DocumentBlockSwagger>) {
const { block, context } = props;
const data = await fetchOpenAPIBlock(block, context.resolveContentRef);
if (!data) {
return null;
}
return (
<OpenAPIOperation
data={data}
context={{
icons: {
chevronDown: <ChevronDown />,
chevronRight: <ChevronRight />,
},
CodeBlock: PlainCodeBlock,
defaultInteractiveOpened: context.mode === 'print',
}}
className="openapi-block"
/>
);
}
function OpenAPIFallback() {
return (
<div
role="status"
aria-busy
className={'openapi-block ' + tcls('flex', 'flex-1', 'flex-col', 'gap-3')}
>
<LoadingPane
tile={12}
style={['rounded-md', 'h-[47px]', '[max-width:calc(48rem-1px)]']}
/>
<LoadingPane
tile={12}
style={['rounded-md', 'h-[35px]', '[max-width:calc(48rem-1px)]']}
/>
<div className={tcls('flex', 'gap-[25px]')}>
<div className={tcls('flex', 'flex-1', 'flex-col', 'gap-3')}>
<LoadingPane tile={24} style={['rounded-md', 'aspect-[2.5/1]', 'w-full']} />
<LoadingPane tile={24} style={['rounded-md', 'aspect-[2.5/1]', 'w-full']} />
</div>
<div className={tcls('flex', 'flex-1', 'flex-col', 'gap-3')}>
<LoadingPane tile={24} style={['rounded-md', 'aspect-[4/1]', 'w-full']} />
<LoadingPane tile={24} style={['rounded-md', 'aspect-[4/1]', 'w-full']} />
</div>
</div>
</div>
);
}