mirror of
https://github.com/Redocly/redoc.git
synced 2025-08-07 13:44:54 +03:00
feat: make dropdown to switch between code samples
This commit is contained in:
parent
f805271d90
commit
b80ab2b1c6
|
@ -6,7 +6,7 @@ import styled from '../styled-components';
|
|||
export { Tab, TabList, TabPanel } from 'react-tabs';
|
||||
|
||||
export const Tabs = styled(ReactTabs)`
|
||||
> ul {
|
||||
.react-tabs__tab-list {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
@ -101,7 +101,7 @@ export const SmallTabs = styled(Tabs)`
|
|||
> .react-tabs__tab-panel {
|
||||
& > div,
|
||||
& > pre {
|
||||
padding: ${props => props.theme.spacing.unit * 2}px 0;
|
||||
padding: ${(props) => props.theme.spacing.unit * 2}px 0;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
|
|
@ -1,52 +1,120 @@
|
|||
import { observer } from 'mobx-react';
|
||||
import * as React from 'react';
|
||||
import { isPayloadSample, OperationModel, RedocNormalizedOptions } from '../../services';
|
||||
import {
|
||||
isPayloadSample,
|
||||
OperationModel,
|
||||
RedocNormalizedOptions,
|
||||
XPayloadSample,
|
||||
} from '../../services';
|
||||
import { PayloadSamples } from '../PayloadSamples/PayloadSamples';
|
||||
import { SourceCodeWithCopy } from '../SourceCode/SourceCode';
|
||||
|
||||
import { RightPanelHeader, Tab, TabList, TabPanel, Tabs } from '../../common-elements';
|
||||
import {
|
||||
DropdownOption,
|
||||
RightPanelHeader,
|
||||
Tab,
|
||||
TabList,
|
||||
TabPanel,
|
||||
Tabs,
|
||||
} from '../../common-elements';
|
||||
import { OptionsContext } from '../OptionsProvider';
|
||||
import { SamplesDropdown, Flex } from './styled.elements';
|
||||
|
||||
export interface RequestSamplesProps {
|
||||
operation: OperationModel;
|
||||
}
|
||||
|
||||
interface RequestSamplesState {
|
||||
codeSampleIdx: number;
|
||||
tabIndex: number;
|
||||
}
|
||||
|
||||
@observer
|
||||
export class RequestSamples extends React.Component<RequestSamplesProps> {
|
||||
export class RequestSamples extends React.Component<RequestSamplesProps, RequestSamplesState> {
|
||||
static contextType = OptionsContext;
|
||||
context: RedocNormalizedOptions;
|
||||
operation: OperationModel;
|
||||
|
||||
state = {
|
||||
codeSampleIdx: 0,
|
||||
tabIndex: 0,
|
||||
};
|
||||
|
||||
handleChangeLang = (option: DropdownOption, updatedTabIndex: number) => {
|
||||
this.setState({
|
||||
codeSampleIdx: option.idx,
|
||||
});
|
||||
if (this.state.tabIndex !== updatedTabIndex) {
|
||||
this.setState({
|
||||
tabIndex: updatedTabIndex,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
handleChangeTab = (index: number) => {
|
||||
this.setState({
|
||||
tabIndex: index,
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const { operation } = this.props;
|
||||
const samples = operation.codeSamples;
|
||||
|
||||
const hasSamples = samples.length > 0;
|
||||
const hideTabList = samples.length === 1 ? this.context.hideSingleRequestSampleTab : false;
|
||||
|
||||
const payloadSample = samples.find((sample) => isPayloadSample(sample));
|
||||
const codeSamples = samples.filter((sample) => !isPayloadSample(sample));
|
||||
const isCodeSamples = codeSamples.length > 0;
|
||||
const options = isCodeSamples
|
||||
? codeSamples.map((codeSample, idx) => {
|
||||
return {
|
||||
idx,
|
||||
value: codeSample.label || codeSample.lang,
|
||||
};
|
||||
})
|
||||
: [];
|
||||
|
||||
return (
|
||||
(hasSamples && (
|
||||
<div>
|
||||
<RightPanelHeader> Request samples </RightPanelHeader>
|
||||
|
||||
<Tabs defaultIndex={0}>
|
||||
<TabList hidden={hideTabList}>
|
||||
{samples.map(sample => (
|
||||
<Tab key={sample.lang + '_' + (sample.label || '')}>
|
||||
{sample.label !== undefined ? sample.label : sample.lang}
|
||||
</Tab>
|
||||
))}
|
||||
</TabList>
|
||||
{samples.map(sample => (
|
||||
<TabPanel key={sample.lang + '_' + (sample.label || '')}>
|
||||
{isPayloadSample(sample) ? (
|
||||
<div>
|
||||
<PayloadSamples content={sample.requestBodyContent} />
|
||||
</div>
|
||||
) : (
|
||||
<SourceCodeWithCopy lang={sample.lang} source={sample.source} />
|
||||
<Tabs selectedIndex={this.state.tabIndex} onSelect={this.handleChangeTab}>
|
||||
<Flex>
|
||||
<TabList hidden={hideTabList}>
|
||||
{payloadSample && (
|
||||
<Tab>
|
||||
{payloadSample.label !== undefined ? payloadSample.label : payloadSample.lang}
|
||||
</Tab>
|
||||
)}
|
||||
{isCodeSamples && <Tab>Code samples</Tab>}
|
||||
</TabList>
|
||||
{isCodeSamples && (
|
||||
<SamplesDropdown
|
||||
value={options[this.state.codeSampleIdx].value}
|
||||
onChange={(option: DropdownOption) =>
|
||||
this.handleChangeLang(option, payloadSample ? 1 : 0)
|
||||
}
|
||||
options={options}
|
||||
/>
|
||||
)}
|
||||
</Flex>
|
||||
{payloadSample && (
|
||||
<TabPanel>
|
||||
<div>
|
||||
<PayloadSamples content={(payloadSample as XPayloadSample).requestBodyContent} />
|
||||
</div>
|
||||
</TabPanel>
|
||||
))}
|
||||
)}
|
||||
{isCodeSamples && (
|
||||
<TabPanel>
|
||||
<SourceCodeWithCopy
|
||||
lang={codeSamples[this.state.codeSampleIdx].lang}
|
||||
source={codeSamples[this.state.codeSampleIdx].source}
|
||||
/>
|
||||
</TabPanel>
|
||||
)}
|
||||
</Tabs>
|
||||
</div>
|
||||
)) ||
|
||||
|
|
26
src/components/RequestSamples/styled.elements.ts
Normal file
26
src/components/RequestSamples/styled.elements.ts
Normal file
|
@ -0,0 +1,26 @@
|
|||
import styled from '../../styled-components';
|
||||
import { InvertedSimpleDropdown } from '../PayloadSamples/styled.elements';
|
||||
import { darken } from 'polished';
|
||||
|
||||
export const Flex = styled.div`
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
`;
|
||||
|
||||
export const SamplesDropdown = styled(InvertedSimpleDropdown)`
|
||||
&& {
|
||||
background-color: ${({ theme }) => theme.codeBlock.backgroundColor};
|
||||
height: 33px;
|
||||
padding: 6px 10px;
|
||||
border: 1px solid ${({ theme }) => darken(0.05, theme.codeBlock.backgroundColor)};
|
||||
border-radius: 5px;
|
||||
&:hover,
|
||||
&:focus-within {
|
||||
border: 1px solid ${({ theme }) => darken(0.05, theme.codeBlock.backgroundColor)};
|
||||
box-shadow: none;
|
||||
}
|
||||
&:focus-within {
|
||||
background-color: ${({ theme }) => theme.codeBlock.backgroundColor};
|
||||
}
|
||||
}
|
||||
`;
|
Loading…
Reference in New Issue
Block a user