'use client'; import * as React from 'react'; import { type ComponentType, useRef, useState } from 'react'; import { createPortal } from 'react-dom'; import * as ReactJSXRuntime from 'react/jsx-runtime'; import type { OpenAPIV3_1 } from '@gitbook/openapi-parser'; import type { OpenAPIClientContext } from './context'; import type { ScalarApiModalProps, ScalarModalControllerRef, ScalarRuntime, } from './ScalarApiModal'; import { t } from './translate'; import type { OpenAPIOperationData } from './types'; let scalarRuntimePromise: Promise | null = null; /** Everything needed to render the client, none of it in the initial bundle. */ type ScalarClient = { runtime: ScalarRuntime; Modal: ComponentType; }; /** * Button which launches the Scalar API Client */ export function ScalarApiButton(props: { method: OpenAPIV3_1.HttpMethods; path: string; securities: OpenAPIOperationData['securities']; servers: OpenAPIOperationData['servers']; specUrl: string; withProxy: boolean; context: OpenAPIClientContext; }) { const { method, path, securities, servers, specUrl, withProxy, context } = props; const [isOpen, setIsOpen] = useState(false); const [isLoading, setIsLoading] = useState(false); const [client, setClient] = useState(null); const controllerRef = useRef(null); return (
{isOpen && client && createPortal( setIsLoading(false)} />, document.body )}
); } /** Fetch the modal chunk and the Scalar runtime in parallel. */ async function loadScalarClient(runtimeURL: string): Promise { const [runtime, mod] = await Promise.all([ loadScalarRuntime(runtimeURL), import('./ScalarApiModal'), ]); return { runtime, Modal: mod.ScalarApiModal }; } async function loadScalarRuntime(runtimeURL: string): Promise { if (!scalarRuntimePromise) { Object.assign(globalThis, { __gitbookScalarReact: React, __gitbookScalarJSXRuntime: ReactJSXRuntime, }); scalarRuntimePromise = import(/* webpackIgnore: true */ runtimeURL).catch((error) => { scalarRuntimePromise = null; throw error; }); } return scalarRuntimePromise; }