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 { DropdownProps } from '../../common-elements/dropdown'; | ||||||
| import { MediaContentModel, MediaTypeModel, SchemaModel } from '../../services/models'; | import { MediaContentModel, MediaTypeModel, SchemaModel } from '../../services/models'; | ||||||
|  | import { DropdownLabel, DropdownWrapper } from '../PayloadSamples/styled.elements'; | ||||||
| 
 | 
 | ||||||
| export interface MediaTypeChildProps { | export interface MediaTypeChildProps { | ||||||
|   schema: SchemaModel; |   schema: SchemaModel; | ||||||
|  | @ -39,11 +40,14 @@ export class MediaTypesSwitch extends React.Component<MediaTypesSwitchProps> { | ||||||
| 
 | 
 | ||||||
|     return ( |     return ( | ||||||
|       <> |       <> | ||||||
|  |         <DropdownWrapper> | ||||||
|  |           <DropdownLabel>Content type</DropdownLabel> | ||||||
|           {this.props.renderDropdown({ |           {this.props.renderDropdown({ | ||||||
|             value: options[activeMimeIdx], |             value: options[activeMimeIdx], | ||||||
|             options, |             options, | ||||||
|             onChange: this.switchMedia, |             onChange: this.switchMedia, | ||||||
|           })} |           })} | ||||||
|  |         </DropdownWrapper> | ||||||
|         {this.props.children(content.active)} |         {this.props.children(content.active)} | ||||||
|       </> |       </> | ||||||
|     ); |     ); | ||||||
|  |  | ||||||
|  | @ -1,17 +1,31 @@ | ||||||
| import * as React from 'react'; | import * as React from 'react'; | ||||||
| 
 | 
 | ||||||
| import { SmallTabs, Tab, TabList, TabPanel } from '../../common-elements'; | import { DropdownProps } from '../../common-elements'; | ||||||
| import { MediaTypeModel } from '../../services/models'; | import { MediaTypeModel } from '../../services/models'; | ||||||
| 
 | 
 | ||||||
| import { Example } from './Example'; | import { Example } from './Example'; | ||||||
| import { NoSampleLabel } from './styled.elements'; | import { Description, DropdownLabel, DropdownWrapper, NoSampleLabel } from './styled.elements'; | ||||||
| 
 | 
 | ||||||
| export interface PayloadSamplesProps { | export interface PayloadSamplesProps { | ||||||
|   mediaType: MediaTypeModel; |   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() { |   render() { | ||||||
|  |     const { activeIdx } = this.state; | ||||||
|     const examples = this.props.mediaType.examples || {}; |     const examples = this.props.mediaType.examples || {}; | ||||||
|     const mimeType = this.props.mediaType.name; |     const mimeType = this.props.mediaType.name; | ||||||
| 
 | 
 | ||||||
|  | @ -22,24 +36,42 @@ export class MediaTypeSamples extends React.Component<PayloadSamplesProps> { | ||||||
|       return noSample; |       return noSample; | ||||||
|     } |     } | ||||||
|     if (examplesNames.length > 1) { |     if (examplesNames.length > 1) { | ||||||
|  |       const options = examplesNames.map((name, idx) => { | ||||||
|  |         return { | ||||||
|  |           label: examples[name].summary || name, | ||||||
|  |           value: idx.toString(), | ||||||
|  |         }; | ||||||
|  |       }); | ||||||
|       return ( |       return ( | ||||||
|         <SmallTabs defaultIndex={0}> |         <> | ||||||
|           <TabList> |           <DropdownWrapper> | ||||||
|             {examplesNames.map(name => ( |             <DropdownLabel>Example</DropdownLabel> | ||||||
|               <Tab key={name}> {examples[name].summary || name} </Tab> |             {this.props.renderDropdown({ | ||||||
|             ))} |               value: options[activeIdx], | ||||||
|           </TabList> |               options, | ||||||
|           {examplesNames.map(name => ( |               onChange: this.switchMedia, | ||||||
|             <TabPanel key={name}> |             })} | ||||||
|  |           </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} /> |                   <Example example={examples[name]} mimeType={mimeType} /> | ||||||
|             </TabPanel> |                 </div> | ||||||
|           ))} |               ) | ||||||
|         </SmallTabs> |             ); | ||||||
|  |           })} | ||||||
|  |         </> | ||||||
|       ); |       ); | ||||||
|     } else { |     } else { | ||||||
|       const name = examplesNames[0]; |       const name = examplesNames[0]; | ||||||
|       return ( |       return ( | ||||||
|         <div> |         <div> | ||||||
|  |           {examples[name].description && <Description>{examples[name].description}</Description>} | ||||||
|           <Example example={examples[name]} mimeType={mimeType} /> |           <Example example={examples[name]} mimeType={mimeType} /> | ||||||
|         </div> |         </div> | ||||||
|       ); |       ); | ||||||
|  |  | ||||||
|  | @ -4,6 +4,7 @@ import { MediaTypeSamples } from './MediaTypeSamples'; | ||||||
| 
 | 
 | ||||||
| import { MediaTypesSwitch } from '../MediaTypeSwitch/MediaTypesSwitch'; | import { MediaTypesSwitch } from '../MediaTypeSwitch/MediaTypesSwitch'; | ||||||
| 
 | 
 | ||||||
|  | import styled from '../../../src/styled-components'; | ||||||
| import { MediaContentModel } from '../../services/models'; | import { MediaContentModel } from '../../services/models'; | ||||||
| import { DropdownOrLabel } from '../DropdownOrLabel/DropdownOrLabel'; | import { DropdownOrLabel } from '../DropdownOrLabel/DropdownOrLabel'; | ||||||
| import { InvertedSimpleDropdown, MimeLabel } from './styled.elements'; | import { InvertedSimpleDropdown, MimeLabel } from './styled.elements'; | ||||||
|  | @ -22,7 +23,15 @@ export class PayloadSamples extends React.Component<PayloadSamplesProps> { | ||||||
| 
 | 
 | ||||||
|     return ( |     return ( | ||||||
|       <MediaTypesSwitch content={mimeContent} renderDropdown={this.renderDropdown}> |       <MediaTypesSwitch content={mimeContent} renderDropdown={this.renderDropdown}> | ||||||
|         {mediaType => <MediaTypeSamples key="samples" mediaType={mediaType} />} |         {mediaType => ( | ||||||
|  |           <SamplesWrapper> | ||||||
|  |             <MediaTypeSamples | ||||||
|  |               key="samples" | ||||||
|  |               mediaType={mediaType} | ||||||
|  |               renderDropdown={this.renderDropdown} | ||||||
|  |             /> | ||||||
|  |           </SamplesWrapper> | ||||||
|  |         )} | ||||||
|       </MediaTypesSwitch> |       </MediaTypesSwitch> | ||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
|  | @ -31,3 +40,7 @@ export class PayloadSamples extends React.Component<PayloadSamplesProps> { | ||||||
|     return <DropdownOrLabel Label={MimeLabel} Dropdown={InvertedSimpleDropdown} {...props} />; |     return <DropdownOrLabel Label={MimeLabel} Dropdown={InvertedSimpleDropdown} {...props} />; | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | const SamplesWrapper = styled.div` | ||||||
|  |   margin-top: 15px; | ||||||
|  | `;
 | ||||||
|  |  | ||||||
|  | @ -1,24 +1,44 @@ | ||||||
| // @ts-ignore
 | // @ts-ignore
 | ||||||
| import Dropdown from 'react-dropdown'; | import Dropdown from 'react-dropdown'; | ||||||
|  | 
 | ||||||
|  | import { transparentize } from 'polished'; | ||||||
| import styled from '../../styled-components'; | import styled from '../../styled-components'; | ||||||
| 
 | 
 | ||||||
| import { StyledDropdown } from '../../common-elements'; | import { StyledDropdown } from '../../common-elements'; | ||||||
| 
 | 
 | ||||||
| export const MimeLabel = styled.div` | 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; |   margin: 0 0 10px 0; | ||||||
|   display: block; |   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)` | export const InvertedSimpleDropdown = styled(StyledDropdown)` | ||||||
|   margin-left: 10px; |   margin-left: 10px; | ||||||
|   text-transform: none; |   text-transform: none; | ||||||
|   font-size: 0.929em; |   font-size: 0.929em; | ||||||
|   border-bottom: 1px solid ${({ theme }) => theme.rightPanel.textColor}; |   padding: 12px; | ||||||
|   margin: 0 0 10px 0; |   margin: 0 0 10px 0; | ||||||
|   display: block; |   display: block; | ||||||
| 
 |   background-color: ${({ theme }) => transparentize(0.6, theme.rightPanel.backgroundColor)}; | ||||||
|  |   .Dropdown-control { | ||||||
|  |     margin-top: 0; | ||||||
|  |   } | ||||||
|   .Dropdown-control, |   .Dropdown-control, | ||||||
|   .Dropdown-control:hover { |   .Dropdown-control:hover { | ||||||
|     font-size: 1em; |     font-size: 1em; | ||||||
|  | @ -34,6 +54,7 @@ export const InvertedSimpleDropdown = styled(StyledDropdown)` | ||||||
|   } |   } | ||||||
|   .Dropdown-menu { |   .Dropdown-menu { | ||||||
|     margin: 0; |     margin: 0; | ||||||
|  |     margin-top: 10px; | ||||||
|   } |   } | ||||||
| `;
 | `;
 | ||||||
| 
 | 
 | ||||||
|  | @ -42,3 +63,8 @@ export const NoSampleLabel = styled.div` | ||||||
|   font-size: 12px; |   font-size: 12px; | ||||||
|   color: #ee807f; |   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