11'use client' ;
22
33import { ApiClientModalProvider , useApiClientModal } from '@scalar/api-client-react' ;
4- import { useEffect , useImperativeHandle , useRef , useState } from 'react' ;
4+ import { useEffect , useImperativeHandle , useMemo , useRef , useState } from 'react' ;
55import { createPortal } from 'react-dom' ;
66
7- import { useEventCallback } from 'usehooks-ts ' ;
7+ import type { OpenAPIV3_1 } from '@gitbook/openapi-parser ' ;
88import { useOpenAPIOperationContext } from './OpenAPIOperationContext' ;
99
1010/**
1111 * Button which launches the Scalar API Client
1212 */
13- export function ScalarApiButton ( {
14- method,
15- path,
16- specUrl,
17- } : {
18- method : string ;
13+ export function ScalarApiButton ( props : {
14+ method : OpenAPIV3_1 . HttpMethods ;
1915 path : string ;
2016 specUrl : string ;
2117} ) {
18+ const { method, path, specUrl } = props ;
2219 const [ isOpen , setIsOpen ] = useState ( false ) ;
2320 const controllerRef = useRef < ScalarModalControllerRef > ( null ) ;
2421 return (
@@ -55,21 +52,18 @@ export function ScalarApiButton({
5552}
5653
5754function ScalarModal ( props : {
58- method : string ;
55+ method : OpenAPIV3_1 . HttpMethods ;
5956 path : string ;
6057 specUrl : string ;
6158 controllerRef : React . Ref < ScalarModalControllerRef > ;
6259} ) {
60+ const { method, path, specUrl, controllerRef } = props ;
6361 return (
6462 < ApiClientModalProvider
65- configuration = { { spec : { url : props . specUrl } } }
66- initialRequest = { { path : props . path , method : props . method } }
63+ configuration = { { spec : { url : specUrl } } }
64+ initialRequest = { { method , path } }
6765 >
68- < ScalarModalController
69- method = { props . method }
70- path = { props . path }
71- controllerRef = { props . controllerRef }
72- />
66+ < ScalarModalController method = { method } path = { path } controllerRef = { controllerRef } />
7367 </ ApiClientModalProvider >
7468 ) ;
7569}
@@ -79,28 +73,32 @@ type ScalarModalControllerRef = {
7973} ;
8074
8175function ScalarModalController ( props : {
82- method : string ;
76+ method : OpenAPIV3_1 . HttpMethods ;
8377 path : string ;
8478 controllerRef : React . Ref < ScalarModalControllerRef > ;
8579} ) {
80+ const { method, path, controllerRef } = props ;
8681 const client = useApiClientModal ( ) ;
87- const openClient = client ?. open ;
82+ const openScalarClient = client ?. open ;
83+ const { onOpenClient : trackClientOpening } = useOpenAPIOperationContext ( ) ;
84+ const openClient = useMemo ( ( ) => {
85+ if ( openScalarClient ) {
86+ return ( ) => {
87+ openScalarClient ( { method, path, _source : 'gitbook' } ) ;
88+ trackClientOpening ( { method, path } ) ;
89+ } ;
90+ }
91+ return null ;
92+ } , [ openScalarClient , method , path , trackClientOpening ] ) ;
8893 useImperativeHandle (
89- props . controllerRef ,
94+ controllerRef ,
9095 ( ) => ( { openClient : openClient ? ( ) => openClient ( ) : undefined } ) ,
9196 [ openClient ]
9297 ) ;
9398
94- // Open the client when the component is mounted.
95- const { onOpenClient } = useOpenAPIOperationContext ( ) ;
96- const trackOpening = useEventCallback ( ( ) => {
97- onOpenClient ( { method : props . method , path : props . path } ) ;
98- } ) ;
99+ // Open at mount
99100 useEffect ( ( ) => {
100- if ( openClient ) {
101- openClient ( ) ;
102- trackOpening ( ) ;
103- }
101+ openClient ?.( ) ;
104102 } , [ openClient ] ) ;
105103 return null ;
106104}
0 commit comments