mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-21 01:53:26 +00:00
Reset to first tab when tabs change in an InteractiveSection (#2407)
This commit is contained in:
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'@gitbook/react-openapi': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Fix tabs being empty for code samples when they are updated dynamically
|
||||||
@@ -3,6 +3,12 @@
|
|||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
|
interface InteractiveSectionTab {
|
||||||
|
key: string;
|
||||||
|
label: string;
|
||||||
|
body: React.ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* To optimize rendering, most of the components are server-components,
|
* To optimize rendering, most of the components are server-components,
|
||||||
* and the interactiveness is mainly handled by a few key components like this one.
|
* and the interactiveness is mainly handled by a few key components like this one.
|
||||||
@@ -19,11 +25,7 @@ export function InteractiveSection(props: {
|
|||||||
toggleOpenIcon?: React.ReactNode;
|
toggleOpenIcon?: React.ReactNode;
|
||||||
toggleCloseIcon?: React.ReactNode;
|
toggleCloseIcon?: React.ReactNode;
|
||||||
/** Tabs of content to display */
|
/** Tabs of content to display */
|
||||||
tabs?: Array<{
|
tabs?: Array<InteractiveSectionTab>;
|
||||||
key: string;
|
|
||||||
label: string;
|
|
||||||
body: React.ReactNode;
|
|
||||||
}>;
|
|
||||||
/** Default tab to have opened */
|
/** Default tab to have opened */
|
||||||
defaultTab?: string;
|
defaultTab?: string;
|
||||||
/** Content of the header */
|
/** Content of the header */
|
||||||
@@ -48,9 +50,9 @@ export function InteractiveSection(props: {
|
|||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const [opened, setOpened] = React.useState(defaultOpened);
|
const [opened, setOpened] = React.useState(defaultOpened);
|
||||||
const [selectedTab, setSelectedTab] = React.useState(defaultTab);
|
const [selectedTabKey, setSelectedTab] = React.useState(defaultTab);
|
||||||
|
const selectedTab: InteractiveSectionTab | undefined =
|
||||||
const tabBody = tabs.find((tab) => tab.key === selectedTab)?.body;
|
tabs.find((tab) => tab.key === selectedTabKey) ?? tabs[0];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@@ -94,7 +96,7 @@ export function InteractiveSection(props: {
|
|||||||
'openapi-select',
|
'openapi-select',
|
||||||
`${className}-tabs-select`,
|
`${className}-tabs-select`,
|
||||||
)}
|
)}
|
||||||
value={selectedTab}
|
value={selectedTab.key}
|
||||||
onChange={(event) => {
|
onChange={(event) => {
|
||||||
setSelectedTab(event.target.value);
|
setSelectedTab(event.target.value);
|
||||||
setOpened(true);
|
setOpened(true);
|
||||||
@@ -107,7 +109,7 @@ export function InteractiveSection(props: {
|
|||||||
))}
|
))}
|
||||||
</select>
|
</select>
|
||||||
) : null}
|
) : null}
|
||||||
{(children || tabBody) && toggeable ? (
|
{(children || selectedTab?.body) && toggeable ? (
|
||||||
<button
|
<button
|
||||||
className={classNames('openapi-section-toggle', `${className}-toggle`)}
|
className={classNames('openapi-section-toggle', `${className}-toggle`)}
|
||||||
onClick={() => setOpened(!opened)}
|
onClick={() => setOpened(!opened)}
|
||||||
@@ -117,10 +119,10 @@ export function InteractiveSection(props: {
|
|||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{(!toggeable || opened) && (children || tabBody) ? (
|
{(!toggeable || opened) && (children || selectedTab?.body) ? (
|
||||||
<div className={classNames('openapi-section-body', `${className}-body`)}>
|
<div className={classNames('openapi-section-body', `${className}-body`)}>
|
||||||
{children}
|
{children}
|
||||||
{tabBody}
|
{selectedTab?.body}
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
{overlay}
|
{overlay}
|
||||||
|
|||||||
Reference in New Issue
Block a user