mirror of
				https://github.com/Redocly/redoc.git
				synced 2025-10-30 23:37:28 +03:00 
			
		
		
		
	fix: organize response examples in dropdown and display description
This commit is contained in:
		
							parent
							
								
									51d3b9b02b
								
							
						
					
					
						commit
						995e557d6d
					
				|  | @ -3,6 +3,7 @@ import * as React from 'react'; | |||
| 
 | ||||
| import { DropdownProps } from '../../common-elements/dropdown'; | ||||
| import { MediaContentModel, MediaTypeModel, SchemaModel } from '../../services/models'; | ||||
| import { DropdownLabel, DropdownWrapper } from '../PayloadSamples/styled.elements'; | ||||
| 
 | ||||
| export interface MediaTypeChildProps { | ||||
|   schema: SchemaModel; | ||||
|  | @ -39,11 +40,14 @@ export class MediaTypesSwitch extends React.Component<MediaTypesSwitchProps> { | |||
| 
 | ||||
|     return ( | ||||
|       <> | ||||
|         {this.props.renderDropdown({ | ||||
|           value: options[activeMimeIdx], | ||||
|           options, | ||||
|           onChange: this.switchMedia, | ||||
|         })} | ||||
|         <DropdownWrapper> | ||||
|           <DropdownLabel>Content type</DropdownLabel> | ||||
|           {this.props.renderDropdown({ | ||||
|             value: options[activeMimeIdx], | ||||
|             options, | ||||
|             onChange: this.switchMedia, | ||||
|           })} | ||||
|         </DropdownWrapper> | ||||
|         {this.props.children(content.active)} | ||||
|       </> | ||||
|     ); | ||||
|  |  | |||
|  | @ -1,17 +1,31 @@ | |||
| import * as React from 'react'; | ||||
| 
 | ||||
| import { SmallTabs, Tab, TabList, TabPanel } from '../../common-elements'; | ||||
| import { DropdownProps } from '../../common-elements'; | ||||
| import { MediaTypeModel } from '../../services/models'; | ||||
| 
 | ||||
| import { Example } from './Example'; | ||||
| import { NoSampleLabel } from './styled.elements'; | ||||
| import { Description, DropdownLabel, DropdownWrapper, NoSampleLabel } from './styled.elements'; | ||||
| 
 | ||||
| export interface PayloadSamplesProps { | ||||
|   mediaType: MediaTypeModel; | ||||
|   renderDropdown: (props: DropdownProps) => JSX.Element; | ||||
| } | ||||
| 
 | ||||
| export class MediaTypeSamples extends React.Component<PayloadSamplesProps> { | ||||
| interface MediaTypeSamplesState { | ||||
|   activeIdx: number; | ||||
| } | ||||
| 
 | ||||
| export class MediaTypeSamples extends React.Component<PayloadSamplesProps, MediaTypeSamplesState> { | ||||
|   state = { | ||||
|     activeIdx: 0, | ||||
|   }; | ||||
|   switchMedia = ({ value }) => { | ||||
|     this.setState({ | ||||
|       activeIdx: parseInt(value, 10), | ||||
|     }); | ||||
|   }; | ||||
|   render() { | ||||
|     const { activeIdx } = this.state; | ||||
|     const examples = this.props.mediaType.examples || {}; | ||||
|     const mimeType = this.props.mediaType.name; | ||||
| 
 | ||||
|  | @ -22,24 +36,42 @@ export class MediaTypeSamples extends React.Component<PayloadSamplesProps> { | |||
|       return noSample; | ||||
|     } | ||||
|     if (examplesNames.length > 1) { | ||||
|       const options = examplesNames.map((name, idx) => { | ||||
|         return { | ||||
|           label: examples[name].summary || name, | ||||
|           value: idx.toString(), | ||||
|         }; | ||||
|       }); | ||||
|       return ( | ||||
|         <SmallTabs defaultIndex={0}> | ||||
|           <TabList> | ||||
|             {examplesNames.map(name => ( | ||||
|               <Tab key={name}> {examples[name].summary || name} </Tab> | ||||
|             ))} | ||||
|           </TabList> | ||||
|           {examplesNames.map(name => ( | ||||
|             <TabPanel key={name}> | ||||
|               <Example example={examples[name]} mimeType={mimeType} /> | ||||
|             </TabPanel> | ||||
|           ))} | ||||
|         </SmallTabs> | ||||
|         <> | ||||
|           <DropdownWrapper> | ||||
|             <DropdownLabel>Example</DropdownLabel> | ||||
|             {this.props.renderDropdown({ | ||||
|               value: options[activeIdx], | ||||
|               options, | ||||
|               onChange: this.switchMedia, | ||||
|             })} | ||||
|           </DropdownWrapper> | ||||
|           {examplesNames.map(name => { | ||||
|             const description = examples[name].description; | ||||
|             const activeValue = options[activeIdx].label; | ||||
| 
 | ||||
|             return ( | ||||
|               (name === activeValue || examples[name].summary === activeValue) && ( | ||||
|                 <div key={name}> | ||||
|                   {description && <Description>{description}</Description>} | ||||
|                   <Example example={examples[name]} mimeType={mimeType} /> | ||||
|                 </div> | ||||
|               ) | ||||
|             ); | ||||
|           })} | ||||
|         </> | ||||
|       ); | ||||
|     } else { | ||||
|       const name = examplesNames[0]; | ||||
|       return ( | ||||
|         <div> | ||||
|           {examples[name].description && <Description>{examples[name].description}</Description>} | ||||
|           <Example example={examples[name]} mimeType={mimeType} /> | ||||
|         </div> | ||||
|       ); | ||||
|  |  | |||
|  | @ -4,6 +4,7 @@ import { MediaTypeSamples } from './MediaTypeSamples'; | |||
| 
 | ||||
| import { MediaTypesSwitch } from '../MediaTypeSwitch/MediaTypesSwitch'; | ||||
| 
 | ||||
| import styled from '../../../src/styled-components'; | ||||
| import { MediaContentModel } from '../../services/models'; | ||||
| import { DropdownOrLabel } from '../DropdownOrLabel/DropdownOrLabel'; | ||||
| import { InvertedSimpleDropdown, MimeLabel } from './styled.elements'; | ||||
|  | @ -22,7 +23,15 @@ export class PayloadSamples extends React.Component<PayloadSamplesProps> { | |||
| 
 | ||||
|     return ( | ||||
|       <MediaTypesSwitch content={mimeContent} renderDropdown={this.renderDropdown}> | ||||
|         {mediaType => <MediaTypeSamples key="samples" mediaType={mediaType} />} | ||||
|         {mediaType => ( | ||||
|           <SamplesWrapper> | ||||
|             <MediaTypeSamples | ||||
|               key="samples" | ||||
|               mediaType={mediaType} | ||||
|               renderDropdown={this.renderDropdown} | ||||
|             /> | ||||
|           </SamplesWrapper> | ||||
|         )} | ||||
|       </MediaTypesSwitch> | ||||
|     ); | ||||
|   } | ||||
|  | @ -31,3 +40,7 @@ export class PayloadSamples extends React.Component<PayloadSamplesProps> { | |||
|     return <DropdownOrLabel Label={MimeLabel} Dropdown={InvertedSimpleDropdown} {...props} />; | ||||
|   }; | ||||
| } | ||||
| 
 | ||||
| const SamplesWrapper = styled.div` | ||||
|   margin-top: 15px; | ||||
| `;
 | ||||
|  |  | |||
|  | @ -1,24 +1,44 @@ | |||
| // @ts-ignore
 | ||||
| import Dropdown from 'react-dropdown'; | ||||
| 
 | ||||
| import { transparentize } from 'polished'; | ||||
| import styled from '../../styled-components'; | ||||
| 
 | ||||
| import { StyledDropdown } from '../../common-elements'; | ||||
| 
 | ||||
| export const MimeLabel = styled.div` | ||||
|   border-bottom: 1px solid rgba(255, 255, 255, 0.9); | ||||
|   padding: 12px; | ||||
|   background-color: ${({ theme }) => transparentize(0.6, theme.rightPanel.backgroundColor)}; | ||||
|   margin: 0 0 10px 0; | ||||
|   display: block; | ||||
|   color: rgba(255, 255, 255, 0.8); | ||||
| `;
 | ||||
| 
 | ||||
| export const DropdownLabel = styled.span` | ||||
|   font-family: ${({ theme }) => theme.typography.headings.fontFamily}; | ||||
|   font-size: 12px; | ||||
|   position: absolute; | ||||
|   z-index: 1; | ||||
|   top: -11px; | ||||
|   left: 12px; | ||||
|   font-weight: ${({ theme }) => theme.typography.fontWeightBold}; | ||||
|   color: ${({ theme }) => transparentize(0.6, theme.rightPanel.textColor)}; | ||||
| `;
 | ||||
| 
 | ||||
| export const DropdownWrapper = styled.div` | ||||
|   position: relative; | ||||
| `;
 | ||||
| 
 | ||||
| export const InvertedSimpleDropdown = styled(StyledDropdown)` | ||||
|   margin-left: 10px; | ||||
|   text-transform: none; | ||||
|   font-size: 0.929em; | ||||
|   border-bottom: 1px solid ${({ theme }) => theme.rightPanel.textColor}; | ||||
|   padding: 12px; | ||||
|   margin: 0 0 10px 0; | ||||
|   display: block; | ||||
| 
 | ||||
|   background-color: ${({ theme }) => transparentize(0.6, theme.rightPanel.backgroundColor)}; | ||||
|   .Dropdown-control { | ||||
|     margin-top: 0; | ||||
|   } | ||||
|   .Dropdown-control, | ||||
|   .Dropdown-control:hover { | ||||
|     font-size: 1em; | ||||
|  | @ -34,6 +54,7 @@ export const InvertedSimpleDropdown = styled(StyledDropdown)` | |||
|   } | ||||
|   .Dropdown-menu { | ||||
|     margin: 0; | ||||
|     margin-top: 10px; | ||||
|   } | ||||
| `;
 | ||||
| 
 | ||||
|  | @ -42,3 +63,8 @@ export const NoSampleLabel = styled.div` | |||
|   font-size: 12px; | ||||
|   color: #ee807f; | ||||
| `;
 | ||||
| 
 | ||||
| export const Description = styled.span` | ||||
|   font-size: 12px; | ||||
|   color: ${({ theme }) => transparentize(0.6, theme.rightPanel.textColor)}; | ||||
| `;
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user