@@ -47,6 +47,8 @@ export default function ApiEndpoint({
4747 Object . keys ( responses ) [ 0 ] || "200"
4848 ) ;
4949 const [ copied , setCopied ] = useState ( false ) ;
50+ const [ paramsCollapsed , setParamsCollapsed ] = useState ( true ) ;
51+ const [ responsesCollapsed , setResponsesCollapsed ] = useState ( true ) ;
5052
5153 const currentBaseUrl = normalizedBaseUrls [ selectedBaseUrl ] ?. url || '' ;
5254 const fullUrl = `${ currentBaseUrl } ${ endpoint } ` ;
@@ -110,48 +112,116 @@ export default function ApiEndpoint({
110112
111113 { params . length > 0 && (
112114 < div className = { styles . section } >
113- < h4 className = { styles . sectionTitle } > 參數</ h4 >
114- < div className = { styles . paramsList } >
115- { params . map ( ( param ) => (
116- < div key = { param . name } className = { styles . param } >
117- < div className = { styles . paramHeader } >
118- < code className = { styles . paramName } > { param . name } </ code >
119- { param . type && < span className = { styles . paramType } > { param . type } </ span > }
120- { param . optional && < span className = { styles . optional } > optional</ span > }
115+ < div className = { styles . collapsibleHeader } onClick = { ( ) => setParamsCollapsed ( ! paramsCollapsed ) } >
116+ < div className = { styles . titleContainer } >
117+ < h4 className = { styles . sectionTitle } > 參數</ h4 >
118+ { paramsCollapsed && (
119+ < div className = { styles . previewTags } >
120+ { params . slice ( 0 , 3 ) . map ( ( param , index ) => (
121+ < span key = { index } className = { `${ styles . previewTag } ${ param . optional ? styles . optional : styles . required } ` } >
122+ { param . name }
123+ </ span >
124+ ) ) }
125+ { params . length > 3 && (
126+ < span className = { styles . moreCount } > +{ params . length - 3 } </ span >
127+ ) }
121128 </ div >
122- < div className = { styles . paramDescription } >
123- { param . description }
124- { param . default && < span className = { styles . default } > (預設: { param . default } )</ span > }
125- </ div >
126- </ div >
127- ) ) }
129+ ) }
130+ </ div >
131+ < button className = { styles . collapseButton } >
132+ < svg
133+ width = "16"
134+ height = "16"
135+ viewBox = "0 0 16 16"
136+ fill = "currentColor"
137+ style = { { transform : paramsCollapsed ? 'rotate(0deg)' : 'rotate(90deg)' } }
138+ >
139+ < path d = "M6 4l4 4-4 4V4z" />
140+ </ svg >
141+ </ button >
128142 </ div >
143+ { ! paramsCollapsed && (
144+ < div className = { styles . paramsList } >
145+ { params . map ( ( param ) => (
146+ < div key = { param . name } className = { styles . param } >
147+ < div className = { styles . paramHeader } >
148+ < code className = { styles . paramName } > { param . name } </ code >
149+ { param . type && < span className = { styles . paramType } > { param . type } </ span > }
150+ { param . optional && < span className = { styles . optional } > optional</ span > }
151+ </ div >
152+ < div className = { styles . paramDescription } >
153+ { param . description }
154+ { param . default && < span className = { styles . default } > (預設: { param . default } )</ span > }
155+ </ div >
156+ </ div >
157+ ) ) }
158+ </ div >
159+ ) }
129160 </ div >
130161 ) }
131162
132163 { Object . keys ( responses ) . length > 0 && (
133164 < div className = { styles . section } >
134- < div className = { styles . responseHeader } >
135- < h4 className = { styles . sectionTitle } > 回傳</ h4 >
136- < select
137- className = { `${ styles . statusSelect } ${ getStatusColor ( selectedStatus ) } ` }
138- value = { selectedStatus }
139- onChange = { ( e ) => setSelectedStatus ( e . target . value ) }
140- >
141- { Object . keys ( responses ) . map ( ( status ) => (
142- < option key = { status } value = { status } >
143- { status } { responses [ status ] . description && `- ${ responses [ status ] . description } ` }
144- </ option >
145- ) ) }
146- </ select >
165+ < div className = { styles . collapsibleHeader } onClick = { ( ) => setResponsesCollapsed ( ! responsesCollapsed ) } >
166+ < div className = { styles . titleContainer } >
167+ < h4 className = { styles . sectionTitle } > 回傳</ h4 >
168+ { responsesCollapsed && (
169+ < div className = { styles . previewTags } >
170+ { Object . keys ( responses ) . slice ( 0 , 4 ) . map ( ( status ) => {
171+ const code = parseInt ( status ) ;
172+ let statusType = 'default' ;
173+ if ( code >= 200 && code < 300 ) statusType = 'success' ;
174+ else if ( code >= 400 && code < 500 ) statusType = 'error' ;
175+ else if ( code >= 500 ) statusType = 'serverError' ;
176+
177+ return (
178+ < span key = { status } className = { `${ styles . previewTag } ${ styles [ statusType ] } ` } >
179+ { status }
180+ </ span >
181+ ) ;
182+ } ) }
183+ { Object . keys ( responses ) . length > 4 && (
184+ < span className = { styles . moreCount } > +{ Object . keys ( responses ) . length - 4 } </ span >
185+ ) }
186+ </ div >
187+ ) }
188+ </ div >
189+ < button className = { styles . collapseButton } >
190+ < svg
191+ width = "16"
192+ height = "16"
193+ viewBox = "0 0 16 16"
194+ fill = "currentColor"
195+ style = { { transform : responsesCollapsed ? 'rotate(0deg)' : 'rotate(90deg)' } }
196+ >
197+ < path d = "M6 4l4 4-4 4V4z" />
198+ </ svg >
199+ </ button >
147200 </ div >
148- < pre className = { styles . codeBlock } >
149- < code
150- dangerouslySetInnerHTML = { {
151- __html : highlightJSON ( JSON . stringify ( responses [ selectedStatus ] ?. data , null , 2 ) )
152- } }
153- />
154- </ pre >
201+ { ! responsesCollapsed && (
202+ < >
203+ < div className = { styles . responseHeader } >
204+ < select
205+ className = { `${ styles . statusSelect } ${ getStatusColor ( selectedStatus ) } ` }
206+ value = { selectedStatus }
207+ onChange = { ( e ) => setSelectedStatus ( e . target . value ) }
208+ >
209+ { Object . keys ( responses ) . map ( ( status ) => (
210+ < option key = { status } value = { status } >
211+ { status } { responses [ status ] . description && `- ${ responses [ status ] . description } ` }
212+ </ option >
213+ ) ) }
214+ </ select >
215+ </ div >
216+ < pre className = { styles . codeBlock } >
217+ < code
218+ dangerouslySetInnerHTML = { {
219+ __html : highlightJSON ( JSON . stringify ( responses [ selectedStatus ] ?. data , null , 2 ) )
220+ } }
221+ />
222+ </ pre >
223+ </ >
224+ ) }
155225 </ div >
156226 ) }
157227 </ div >
0 commit comments