Skip to content

Commit f774f9b

Browse files
authored
Fix all tabs behaviour in OpenAPI blocks (#2912)
1 parent 29dc7cc commit f774f9b

11 files changed

+175
-140
lines changed

packages/react-openapi/src/InteractiveSection.tsx

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import clsx from 'clsx';
44
import { useRef, useState } from 'react';
55
import { mergeProps, useButton, useDisclosure, useFocusRing } from 'react-aria';
66
import { useDisclosureState } from 'react-stately';
7+
import { Section, SectionBody, SectionHeader, SectionHeaderContent } from './StaticSection';
78

89
interface InteractiveSectionTab {
910
key: string;
@@ -63,7 +64,7 @@ export function InteractiveSection(props: {
6364
const { isFocusVisible, focusProps } = useFocusRing();
6465

6566
return (
66-
<div
67+
<Section
6768
id={id}
6869
className={clsx(
6970
'openapi-section',
@@ -73,20 +74,15 @@ export function InteractiveSection(props: {
7374
)}
7475
>
7576
{header ? (
76-
<div
77+
<SectionHeader
7778
onClick={() => {
7879
if (toggeable) {
7980
state.toggle();
8081
}
8182
}}
82-
className={clsx('openapi-section-header', `${className}-header`)}
83+
className={className}
8384
>
84-
<div
85-
className={clsx(
86-
'openapi-section-header-content',
87-
`${className}-header-content`
88-
)}
89-
>
85+
<SectionHeaderContent className={className}>
9086
{(children || selectedTab?.body) && toggeable ? (
9187
<button
9288
{...mergeProps(buttonProps, focusProps)}
@@ -102,7 +98,7 @@ export function InteractiveSection(props: {
10298
</button>
10399
) : null}
104100
{header}
105-
</div>
101+
</SectionHeaderContent>
106102
<div
107103
className={clsx(
108104
'openapi-section-header-controls',
@@ -133,23 +129,19 @@ export function InteractiveSection(props: {
133129
</select>
134130
) : null}
135131
</div>
136-
</div>
132+
</SectionHeader>
137133
) : null}
138134
{(!toggeable || state.isExpanded) && (children || selectedTab?.body) ? (
139-
<div
140-
ref={panelRef}
141-
{...panelProps}
142-
className={clsx('openapi-section-body', `${className}-body`)}
143-
>
135+
<SectionBody ref={panelRef} {...panelProps} className={className}>
144136
{children}
145137
{selectedTab?.body}
146-
</div>
138+
</SectionBody>
147139
) : null}
148140
{overlay ? (
149141
<div className={clsx('openapi-section-overlay', `${className}-overlay`)}>
150142
{overlay}
151143
</div>
152144
) : null}
153-
</div>
145+
</Section>
154146
);
155147
}

packages/react-openapi/src/OpenAPICodeSample.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { InteractiveSection } from './InteractiveSection';
21
import { OpenAPITabs, OpenAPITabsList, OpenAPITabsPanels } from './OpenAPITabs';
2+
import { StaticSection } from './StaticSection';
33
import { type CodeSampleInput, codeSampleGenerators } from './code-samples';
44
import { generateMediaTypeExample, generateSchemaExample } from './generateSchemaExample';
55
import { stringifyOpenAPI } from './stringifyOpenAPI';
@@ -117,9 +117,9 @@ export function OpenAPICodeSample(props: {
117117

118118
return (
119119
<OpenAPITabs stateKey={createStateKey('codesample')} items={samples}>
120-
<InteractiveSection header={<OpenAPITabsList />} className="openapi-codesample">
120+
<StaticSection header={<OpenAPITabsList />} className="openapi-codesample">
121121
<OpenAPITabsPanels />
122-
</InteractiveSection>
122+
</StaticSection>
123123
</OpenAPITabs>
124124
);
125125
}

packages/react-openapi/src/OpenAPIDisclosure.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
'use client';
12
import type React from 'react';
23
import { useRef } from 'react';
34
import { mergeProps, useButton, useDisclosure, useFocusRing } from 'react-aria';

packages/react-openapi/src/OpenAPIDisclosureGroup.tsx

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
'use client';
2+
3+
import { createContext, useContext, useRef, useState } from 'react';
4+
import { mergeProps, useButton, useDisclosure, useFocusRing, useId } from 'react-aria';
5+
import {
6+
type DisclosureGroupProps,
7+
type DisclosureGroupState,
8+
useDisclosureGroupState,
9+
useDisclosureState,
10+
} from 'react-stately';
11+
112
interface Props {
213
groups: TDisclosureGroup[];
314
icon?: React.ReactNode;
@@ -13,15 +24,6 @@ type TDisclosureGroup = {
1324
}[];
1425
};
1526

16-
import { createContext, useContext, useRef, useState } from 'react';
17-
import { mergeProps, useButton, useDisclosure, useFocusRing, useId } from 'react-aria';
18-
import {
19-
type DisclosureGroupProps,
20-
type DisclosureGroupState,
21-
useDisclosureGroupState,
22-
useDisclosureState,
23-
} from 'react-stately';
24-
2527
const DisclosureGroupStateContext = createContext<DisclosureGroupState | null>(null);
2628

2729
/**

packages/react-openapi/src/OpenAPIResponseExample.tsx

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { OpenAPIV3 } from '@gitbook/openapi-parser';
2-
import { InteractiveSection } from './InteractiveSection';
32
import { OpenAPITabs, OpenAPITabsList, OpenAPITabsPanels } from './OpenAPITabs';
3+
import { StaticSection } from './StaticSection';
44
import { generateSchemaExample } from './generateSchemaExample';
55
import { json2xml } from './json2xml';
66
import { stringifyOpenAPI } from './stringifyOpenAPI';
@@ -84,9 +84,9 @@ export function OpenAPIResponseExample(props: {
8484

8585
return (
8686
<OpenAPITabs stateKey={createStateKey('response-example')} items={tabs}>
87-
<InteractiveSection header={<OpenAPITabsList />} className="openapi-response-example">
87+
<StaticSection header={<OpenAPITabsList />} className="openapi-response-example">
8888
<OpenAPITabsPanels />
89-
</InteractiveSection>
89+
</StaticSection>
9090
</OpenAPITabs>
9191
);
9292
}
@@ -134,12 +134,9 @@ function OpenAPIResponse(props: {
134134

135135
return (
136136
<OpenAPITabs stateKey={createStateKey('response-media-types')} items={tabs}>
137-
<InteractiveSection
138-
header={<OpenAPITabsList />}
139-
className="openapi-response-media-types"
140-
>
137+
<StaticSection header={<OpenAPITabsList />} className="openapi-response-media-types">
141138
<OpenAPITabsPanels />
142-
</InteractiveSection>
139+
</StaticSection>
143140
</OpenAPITabs>
144141
);
145142
}
@@ -173,23 +170,19 @@ function OpenAPIResponseMediaType(props: {
173170
key: example.key,
174171
label: example.example.summary || example.key,
175172
body: (
176-
<OpenAPIExample
177-
example={firstExample.example}
178-
context={props.context}
179-
syntax={syntax}
180-
/>
173+
<OpenAPIExample example={example.example} context={props.context} syntax={syntax} />
181174
),
182175
};
183176
});
184177

185178
return (
186179
<OpenAPITabs stateKey={createStateKey('response-media-type-examples')} items={tabs}>
187-
<InteractiveSection
180+
<StaticSection
188181
header={<OpenAPITabsList />}
189182
className="openapi-response-media-type-examples"
190183
>
191184
<OpenAPITabsPanels />
192-
</InteractiveSection>
185+
</StaticSection>
193186
</OpenAPITabs>
194187
);
195188
}

packages/react-openapi/src/OpenAPIResponses.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import type { OpenAPIV3, OpenAPIV3_1 } from '@gitbook/openapi-parser';
2-
import { InteractiveSection } from './InteractiveSection';
32
import { Markdown } from './Markdown';
43
import { OpenAPIDisclosureGroup } from './OpenAPIDisclosureGroup';
54
import { OpenAPIResponse } from './OpenAPIResponse';
5+
import { StaticSection } from './StaticSection';
66
import type { OpenAPIClientContext } from './types';
77

88
/**
@@ -15,7 +15,7 @@ export function OpenAPIResponses(props: {
1515
const { responses, context } = props;
1616

1717
return (
18-
<InteractiveSection header="Responses" className="openapi-responses">
18+
<StaticSection header="Responses" className="openapi-responses">
1919
<OpenAPIDisclosureGroup
2020
allowsMultipleExpanded
2121
icon={context.icons.chevronRight}
@@ -58,6 +58,6 @@ export function OpenAPIResponses(props: {
5858
}
5959
)}
6060
/>
61-
</InteractiveSection>
61+
</StaticSection>
6262
);
6363
}

packages/react-openapi/src/OpenAPISchema.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,9 @@ export function OpenAPISchemaProperties(props: {
119119

120120
return (
121121
<div id={id} className="openapi-schema-properties">
122-
{properties.map((property) => (
122+
{properties.map((property, index) => (
123123
<OpenAPISchemaProperty
124-
key={property.propertyName}
124+
key={index}
125125
circularRefs={circularRefs}
126126
{...property}
127127
context={context}

packages/react-openapi/src/OpenAPISpec.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
'use client';
2-
31
import type { OpenAPI } from '@gitbook/openapi-parser';
42

5-
import { InteractiveSection } from './InteractiveSection';
63
import { OpenAPIRequestBody } from './OpenAPIRequestBody';
74
import { OpenAPIResponses } from './OpenAPIResponses';
85
import { OpenAPISchemaProperties } from './OpenAPISchema';
96
import { OpenAPISecurities } from './OpenAPISecurities';
7+
import { StaticSection } from './StaticSection';
108
import type { OpenAPIClientContext, OpenAPIOperationData } from './types';
119
import { parameterToProperty } from './utils';
1210

@@ -32,7 +30,7 @@ export function OpenAPISpec(props: { data: OpenAPIOperationData; context: OpenAP
3230

3331
{parameterGroups.map((group) => {
3432
return (
35-
<InteractiveSection
33+
<StaticSection
3634
key={group.key}
3735
className="openapi-parameters"
3836
header={group.label}
@@ -41,7 +39,7 @@ export function OpenAPISpec(props: { data: OpenAPIOperationData; context: OpenAP
4139
properties={group.parameters.map(parameterToProperty)}
4240
context={context}
4341
/>
44-
</InteractiveSection>
42+
</StaticSection>
4543
);
4644
})}
4745

0 commit comments

Comments
 (0)