feat: make dropdown to switch between code samples

This commit is contained in:
Anya Stasiuk 2020-10-07 13:53:31 +03:00
parent f805271d90
commit b80ab2b1c6
3 changed files with 117 additions and 23 deletions

View File

@ -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;
}
}
`;

View File

@ -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>
)) ||

View 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};
}
}
`;