diff --git a/.changeset/quiet-doors-double.md b/.changeset/quiet-doors-double.md new file mode 100644 index 000000000..ee5e81732 --- /dev/null +++ b/.changeset/quiet-doors-double.md @@ -0,0 +1,6 @@ +--- +'@gitbook/react-openapi': minor +'gitbook': patch +--- + +Rollback of scalar modal while fixing perf issue diff --git a/bun.lockb b/bun.lockb index e0b65a931..1371ed794 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index 15fcd3d3d..f4454cf2f 100644 --- a/package.json +++ b/package.json @@ -28,5 +28,8 @@ }, "patchedDependencies": { "@vercel/next@4.3.6": "patches/@vercel%2Fnext@4.3.6.patch" + }, + "dependencies": { + "@scalar/api-client-react": "0.3.7" } } diff --git a/packages/gitbook/src/components/DocumentView/OpenAPI/OpenAPI.tsx b/packages/gitbook/src/components/DocumentView/OpenAPI/OpenAPI.tsx index c05cac1a8..83c9f5d19 100644 --- a/packages/gitbook/src/components/DocumentView/OpenAPI/OpenAPI.tsx +++ b/packages/gitbook/src/components/DocumentView/OpenAPI/OpenAPI.tsx @@ -29,7 +29,7 @@ export async function OpenAPI(props: BlockProps) { async function OpenAPIBody(props: BlockProps) { const { block, context } = props; - const { data, specUrl, error } = await fetchOpenAPIBlock(block, context.resolveContentRef); + const { data, error } = await fetchOpenAPIBlock(block, context.resolveContentRef); if (error) { return ( @@ -41,7 +41,7 @@ async function OpenAPIBody(props: BlockProps) { ); } - if (!data || !specUrl) { + if (!data) { return null; } @@ -55,7 +55,6 @@ async function OpenAPIBody(props: BlockProps) { }, CodeBlock: PlainCodeBlock, defaultInteractiveOpened: context.mode === 'print', - specUrl, id: block.meta?.id, }} className="openapi-block" diff --git a/packages/gitbook/src/components/DocumentView/OpenAPI/scalar.css b/packages/gitbook/src/components/DocumentView/OpenAPI/scalar.css index f75a53ecc..e23957d82 100644 --- a/packages/gitbook/src/components/DocumentView/OpenAPI/scalar.css +++ b/packages/gitbook/src/components/DocumentView/OpenAPI/scalar.css @@ -1,7 +1,4 @@ -@import '@scalar/api-client-react/style.css'; - .light .scalar-modal-layout, -.light .scalar-app, .light .scalar { --scalar-color-1: color-mix( in srgb, @@ -53,13 +50,8 @@ --scalar-button-1: rgb(49 53 56); --scalar-button-1-color: #fff; --scalar-button-1-hover: rgb(28 31 33); - - --scalar-shadow-1: 0 1px 3px 0 rgba(0, 0, 0, 0.11); - --scalar-shadow-2: rgba(0, 0, 0, 0.08) 0px 13px 20px 0px, rgba(0, 0, 0, 0.08) 0px 3px 8px 0px, - #eeeeed 0px 0 0 1px; } .dark .scalar-modal-layout, -.dark .scalar-app, .dark .scalar { --scalar-color-1: color-mix( in srgb, @@ -110,13 +102,8 @@ --scalar-button-1: #f6f6f6; --scalar-button-1-color: #000; --scalar-button-1-hover: #e7e7e7; - - --scalar-shadow-1: 0 1px 3px 0 rgb(0, 0, 0, 0.1); - --scalar-shadow-2: rgba(15, 15, 15, 0.2) 0px 3px 6px, rgba(15, 15, 15, 0.4) 0px 9px 24px, - 0 0 0 1px rgba(255, 255, 255, 0.1); } .scalar-modal-layout, -.scalar-app, .scalar { --scalar-font: initial; --scalar-font-code: var(--font-mono); @@ -178,7 +165,7 @@ .scalar-api-client__close:hover { cursor: pointer; } -.scalar .scalar-app-layout { +.scalar .scalar-app { background: var(--scalar-background-3); height: calc(100dvh - 100px); max-width: 1280px; @@ -215,6 +202,23 @@ cursor: pointer; animation: scalardrawerexitfadein 0.35s forwards; } +.scalar .scalar-app-exit:before { + content: '\00d7'; + font-family: sans-serif; + position: absolute; + top: 0; + right: 0; + font-size: 30px; + font-weight: 100; + line-height: 50px; + right: 12px; + text-align: center; + color: white; + opacity: 0.6; +} +.scalar .scalar-app-exit:hover:before { + opacity: 1; +} @keyframes scalardrawerexitfadein { from { opacity: 0; @@ -301,6 +305,11 @@ scrollbar-width: thin; -webkit-overflow-scrolling: touch; } +@supports (-moz-appearance: none) { + .scalar .custom-scroll { + padding-right: 12px; + } +} .scalar .custom-scroll:hover { scrollbar-color: rgba(0, 0, 0, 0.24) transparent; } @@ -338,18 +347,3 @@ padding-right: 12px; } } -.dark .scalar .client-wrapper-bg-color { - background: linear-gradient( - color-mix(in srgb, var(--tw-bg-base) 6%, transparent) 1%, - color-mix(in srgb, var(--scalar-background-1) 30%, black) 9% - ); -} -.light .scalar .client-wrapper-bg-color { - background-color: var(--scalar-background-2) !important; -} -.scalar .gitbook-show { - display: block !important; -} -.scalar .gitbook-hidden { - display: none !important; -} diff --git a/packages/gitbook/src/lib/openapi.ts b/packages/gitbook/src/lib/openapi.ts index 4e9b19a4d..18aff1cfc 100644 --- a/packages/gitbook/src/lib/openapi.ts +++ b/packages/gitbook/src/lib/openapi.ts @@ -19,12 +19,12 @@ export async function fetchOpenAPIBlock( block: DocumentBlockSwagger, resolveContentRef: (ref: ContentRef) => Promise, ): Promise< - | { data: OpenAPIOperationData | null; specUrl: string | null; error?: undefined } - | { error: OpenAPIFetchError; data?: undefined; specUrl?: undefined } + | { data: OpenAPIOperationData | null; error?: undefined } + | { error: OpenAPIFetchError; data?: undefined } > { const resolved = block.data.ref ? await resolveContentRef(block.data.ref) : null; if (!resolved || !block.data.path || !block.data.method) { - return { data: null, specUrl: null }; + return { data: null }; } try { @@ -37,7 +37,7 @@ export async function fetchOpenAPIBlock( fetcher, ); - return { data, specUrl: resolved.href }; + return { data }; } catch (error) { if (error instanceof OpenAPIFetchError) { return { error }; diff --git a/packages/react-openapi/package.json b/packages/react-openapi/package.json index ba3727613..4a6390e28 100644 --- a/packages/react-openapi/package.json +++ b/packages/react-openapi/package.json @@ -10,7 +10,8 @@ }, "version": "0.6.0", "dependencies": { - "@scalar/api-client-react": "1.0.20", + "@scalar/api-client-react": "0.3.7", + "@scalar/oas-utils": "0.1.6", "classnames": "^2.5.1", "flatted": "^3.2.9", "openapi-types": "^12.1.3", diff --git a/packages/react-openapi/src/OpenAPICodeSample.tsx b/packages/react-openapi/src/OpenAPICodeSample.tsx index c94289869..ae0d4b552 100644 --- a/packages/react-openapi/src/OpenAPICodeSample.tsx +++ b/packages/react-openapi/src/OpenAPICodeSample.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { CodeSampleInput, codeSampleGenerators } from './code-samples'; -import { OpenAPIOperationData } from './fetchOpenAPIOperation'; +import { OpenAPIOperationData, toJSON } from './fetchOpenAPIOperation'; import { generateMediaTypeExample } from './generateSchemaExample'; import { InteractiveSection } from './InteractiveSection'; import { getServersURL } from './OpenAPIServerURL'; @@ -70,6 +70,11 @@ export function OpenAPICodeSample(props: { return null; } + async function fetchOperationData() { + 'use server'; + return toJSON(data); + } + return ( + ) } /> diff --git a/packages/react-openapi/src/OpenAPIOperation.tsx b/packages/react-openapi/src/OpenAPIOperation.tsx index 505f9922f..ead87ffd3 100644 --- a/packages/react-openapi/src/OpenAPIOperation.tsx +++ b/packages/react-openapi/src/OpenAPIOperation.tsx @@ -8,7 +8,7 @@ import { OpenAPIResponseExample } from './OpenAPIResponseExample'; import { OpenAPIServerURL } from './OpenAPIServerURL'; import { OpenAPISpec } from './OpenAPISpec'; import { OpenAPIClientContext, OpenAPIContextProps } from './types'; -import { ApiClientModalProvider } from '@scalar/api-client-react'; +import { ScalarApiClient } from './ScalarApiButton'; /** * Display an interactive OpenAPI operation. @@ -23,15 +23,11 @@ export function OpenAPIOperation(props: { const clientContext: OpenAPIClientContext = { defaultInteractiveOpened: context.defaultInteractiveOpened, - specUrl: context.specUrl, icons: context.icons, }; return ( - +

@@ -67,6 +63,6 @@ export function OpenAPIOperation(props: {

-
+ ); } diff --git a/packages/react-openapi/src/ScalarApiButton.tsx b/packages/react-openapi/src/ScalarApiButton.tsx index 21b0b0ed1..02d9ffaa1 100644 --- a/packages/react-openapi/src/ScalarApiButton.tsx +++ b/packages/react-openapi/src/ScalarApiButton.tsx @@ -1,17 +1,44 @@ 'use client'; - -import { useApiClientModal } from '@scalar/api-client-react'; +import { + Cookie, + getHarRequest, + getParametersFromOperation, + type TransformedOperation, + getRequestFromOperation, + Query, + Header, + RequestBody, +} from '@scalar/oas-utils'; import React from 'react'; +import { OpenAPIOperationData, fromJSON } from './fetchOpenAPIOperation'; + +const ApiClientReact = React.lazy(async () => { + const mod = await import('@scalar/api-client-react'); + return { default: mod.ApiClientReact }; +}); + +const ScalarContext = React.createContext< + (fetchOperationData: () => Promise) => void +>(() => {}); + /** * Button which launches the Scalar API Client */ -export function ScalarApiButton() { - const client = useApiClientModal(); +export function ScalarApiButton(props: { + fetchOperationData: () => Promise; +}) { + const { fetchOperationData } = props; + const open = React.useContext(ScalarContext); return (
-