mirror of
				https://github.com/Redocly/redoc.git
				synced 2025-10-30 15:27:27 +03:00 
			
		
		
		
	feat: theme hooks experimental hooks
This commit is contained in:
		
							parent
							
								
									b2c3c00e8c
								
							
						
					
					
						commit
						55bd8535b4
					
				|  | @ -2,6 +2,7 @@ import { transparentize } from 'polished'; | |||
| import * as React from 'react'; | ||||
| 
 | ||||
| import styled, { | ||||
|   extensionsHook, | ||||
|   ResolvedThemeInterface, | ||||
|   StyledComponentClass, | ||||
|   withProps, | ||||
|  | @ -75,6 +76,8 @@ export const PropertyNameCell = withProps<{ kind?: string }>(PropertyCell.extend | |||
|   } | ||||
| 
 | ||||
|   ${({ kind }) => (kind !== 'field' ? 'font-style: italic' : '')}; | ||||
| 
 | ||||
|   ${extensionsHook('PropertyNameCell')}; | ||||
| `;
 | ||||
| 
 | ||||
| export const PropertyDetailsCell = styled.td` | ||||
|  |  | |||
|  | @ -1,7 +1,12 @@ | |||
| import * as React from 'react'; | ||||
| import { InterpolationFunction, Styles, ThemeProps } from 'styled-components'; | ||||
| 
 | ||||
| import styled, { css, ResolvedThemeInterface, StyledComponentClass } from '../styled-components'; | ||||
| import styled, { | ||||
|   css, | ||||
|   extensionsHook, | ||||
|   ResolvedThemeInterface, | ||||
|   StyledComponentClass, | ||||
| } from '../styled-components'; | ||||
| 
 | ||||
| const headerFontSize = { | ||||
|   1: '1.85714em', | ||||
|  | @ -18,16 +23,28 @@ export const headerCommonMixin = level => css` | |||
| export const H1 = styled.h1` | ||||
|   ${headerCommonMixin(1)}; | ||||
|   color: ${props => props.theme.colors.main}; | ||||
| 
 | ||||
|   ${extensionsHook('H1')}; | ||||
| `;
 | ||||
| 
 | ||||
| export const H2 = styled.h2` | ||||
|   ${headerCommonMixin(2)}; | ||||
|   color: black; | ||||
| 
 | ||||
|   ${extensionsHook('H2')}; | ||||
| `;
 | ||||
| 
 | ||||
| export const H3 = styled.h2` | ||||
|   ${headerCommonMixin(3)}; | ||||
|   color: black; | ||||
| 
 | ||||
|   ${extensionsHook('H3')}; | ||||
| `;
 | ||||
| 
 | ||||
| export const RightPanelHeader = styled.h3` | ||||
|   color: ${({ theme }) => theme.rightPanel.textColor}; | ||||
| 
 | ||||
|   ${extensionsHook('RightPanelHeader')}; | ||||
| `;
 | ||||
| 
 | ||||
| export const UnderlinedHeader = styled.h5` | ||||
|  | @ -38,4 +55,6 @@ export const UnderlinedHeader = styled.h5` | |||
|   text-transform: uppercase; | ||||
|   font-size: 0.929em; | ||||
|   line-height: 20px; | ||||
| 
 | ||||
|   ${extensionsHook('UnderlinedHeader')}; | ||||
| `;
 | ||||
|  |  | |||
|  | @ -7,6 +7,7 @@ import { MiddlePanel, Row } from '../../common-elements/'; | |||
| import { Markdown } from '../Markdown/Markdown'; | ||||
| import { SecurityDefs } from '../SecuritySchemes/SecuritySchemes'; | ||||
| 
 | ||||
| import { StyledMarkdownBlock } from '../Markdown/styled.elements'; | ||||
| import { | ||||
|   ApiHeader, | ||||
|   DownloadButton, | ||||
|  | @ -77,22 +78,23 @@ export class ApiInfo extends React.Component<ApiInfoProps> { | |||
|               </DownloadButton> | ||||
|             </p> | ||||
|           )} | ||||
|           <StyledMarkdownBlock> | ||||
|             {((info.license || info.contact || info.termsOfService) && ( | ||||
|               <InfoSpanBoxWrap> | ||||
|                 <InfoSpanBox> | ||||
|                   {email} {website} {license} {terms} | ||||
|                 </InfoSpanBox> | ||||
|               </InfoSpanBoxWrap> | ||||
|             )) || | ||||
|               null} | ||||
| 
 | ||||
|           {((info.license || info.contact || info.termsOfService) && ( | ||||
|             <InfoSpanBoxWrap> | ||||
|               <InfoSpanBox> | ||||
|                 {email} {website} {license} {terms} | ||||
|               </InfoSpanBox> | ||||
|             </InfoSpanBoxWrap> | ||||
|           )) || | ||||
|             null} | ||||
| 
 | ||||
|           {(externalDocs && ( | ||||
|             <p> | ||||
|               <a href={externalDocs.url}>{externalDocs.description || externalDocs.url}</a> | ||||
|             </p> | ||||
|           )) || | ||||
|             null} | ||||
|             {(externalDocs && ( | ||||
|               <p> | ||||
|                 <a href={externalDocs.url}>{externalDocs.description || externalDocs.url}</a> | ||||
|               </p> | ||||
|             )) || | ||||
|               null} | ||||
|           </StyledMarkdownBlock> | ||||
|         </MiddlePanel> | ||||
|       </Row> | ||||
|     ); | ||||
|  |  | |||
|  | @ -1,7 +1,11 @@ | |||
| import { AnchorHTMLAttributes, ClassAttributes, HTMLAttributes } from 'react'; | ||||
| 
 | ||||
| import { H1, MiddlePanel } from '../../common-elements'; | ||||
| import styled, { ResolvedThemeInterface, StyledComponentClass } from '../../styled-components'; | ||||
| import styled, { | ||||
|   extensionsHook, | ||||
|   ResolvedThemeInterface, | ||||
|   StyledComponentClass, | ||||
| } from '../../styled-components'; | ||||
| 
 | ||||
| const delimiterWidth = 15; | ||||
| 
 | ||||
|  | @ -10,6 +14,8 @@ export const ApiInfoWrap = MiddlePanel; | |||
| export const ApiHeader = H1.extend` | ||||
|   margin-top: 0; | ||||
|   margin-bottom: 0.5em; | ||||
| 
 | ||||
|   ${extensionsHook('ApiHeader')}; | ||||
| `;
 | ||||
| 
 | ||||
| export const DownloadButton = styled.a` | ||||
|  | @ -20,6 +26,8 @@ export const DownloadButton = styled.a` | |||
|   padding: 4px 8px 4px; | ||||
|   display: inline-block; | ||||
|   text-decoration: none; | ||||
| 
 | ||||
|   ${extensionsHook('DownloadButton')}; | ||||
| `;
 | ||||
| 
 | ||||
| export const InfoSpan = styled.span` | ||||
|  |  | |||
|  | @ -4,6 +4,7 @@ import { InterpolationFunction, Styles, ThemeProps } from 'styled-components'; | |||
| import { headerCommonMixin, linkifyMixin } from '../../common-elements'; | ||||
| import styled, { | ||||
|   css, | ||||
|   extensionsHook, | ||||
|   ResolvedThemeInterface, | ||||
|   StyledComponentClass, | ||||
|   withProps, | ||||
|  | @ -132,4 +133,19 @@ export const StyledMarkdownBlock = withProps<{ dense?: boolean; inline?: boolean | |||
|   } | ||||
| 
 | ||||
|   ${linkifyMixin('.share-link')}; | ||||
| 
 | ||||
|   ${extensionsHook('Markdown')}; | ||||
| 
 | ||||
|   a { | ||||
|     text-decoration: none; | ||||
|     color: ${props => props.theme.links.color}; | ||||
| 
 | ||||
|     &:visited { | ||||
|       color: ${props => props.theme.links.visited}; | ||||
|     } | ||||
| 
 | ||||
|     &:hover { | ||||
|       color: ${props => props.theme.links.hover}; | ||||
|     } | ||||
|   } | ||||
| `;
 | ||||
|  |  | |||
|  | @ -32,19 +32,6 @@ export const RedocWrap = styled.div` | |||
|   .redoc-markdown h1 { | ||||
|     padding-top: ${props => props.theme.spacingUnit * 4}px; | ||||
|   } | ||||
| 
 | ||||
|   a { | ||||
|     text-decoration: none; | ||||
|     color: ${props => props.theme.links.color}; | ||||
| 
 | ||||
|     &:visited { | ||||
|       color: ${props => props.theme.links.visited}; | ||||
|     } | ||||
| 
 | ||||
|     &:hover { | ||||
|       color: ${props => props.theme.links.hover}; | ||||
|     } | ||||
|   } | ||||
| `;
 | ||||
| 
 | ||||
| export const ApiContentWrap = styled.div` | ||||
|  |  | |||
|  | @ -4,7 +4,7 @@ import { OperationModel } from '../../services/models'; | |||
| import { PayloadSamples } from '../PayloadSamples/PayloadSamples'; | ||||
| import { SourceCodeWithCopy } from '../SourceCode/SourceCode'; | ||||
| 
 | ||||
| import { Tab, TabList, TabPanel, Tabs } from '../../common-elements'; | ||||
| import { RightPanelHeader, Tab, TabList, TabPanel, Tabs } from '../../common-elements'; | ||||
| 
 | ||||
| export interface RequestSamplesProps { | ||||
|   operation: OperationModel; | ||||
|  | @ -24,7 +24,7 @@ export class RequestSamples extends React.Component<RequestSamplesProps> { | |||
|     return ( | ||||
|       (hasSamples && ( | ||||
|         <div> | ||||
|           <h3> Request samples </h3> | ||||
|           <RightPanelHeader> Request samples </RightPanelHeader> | ||||
| 
 | ||||
|           <Tabs defaultIndex={0}> | ||||
|             <TabList> | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ import * as React from 'react'; | |||
| 
 | ||||
| import { MediaContentModel, OperationModel } from '../../services/models'; | ||||
| 
 | ||||
| import { Tab, TabList, TabPanel, Tabs } from '../../common-elements'; | ||||
| import { RightPanelHeader, Tab, TabList, TabPanel, Tabs } from '../../common-elements'; | ||||
| import { PayloadSamples } from '../PayloadSamples/PayloadSamples'; | ||||
| 
 | ||||
| export interface ResponseSamplesProps { | ||||
|  | @ -23,7 +23,7 @@ export class ResponseSamples extends React.Component<ResponseSamplesProps> { | |||
|     return ( | ||||
|       (responses.length > 0 && ( | ||||
|         <div> | ||||
|           <h3> Response samples </h3> | ||||
|           <RightPanelHeader> Response samples </RightPanelHeader> | ||||
| 
 | ||||
|           <Tabs defaultIndex={0}> | ||||
|             <TabList> | ||||
|  |  | |||
|  | @ -98,7 +98,14 @@ export class RedocNormalizedOptions { | |||
|   unstable_ignoreMimeParameters: boolean; | ||||
| 
 | ||||
|   constructor(raw: RedocRawOptions) { | ||||
|     let hook; | ||||
|     if (raw.theme && raw.theme.extensionsHook) { | ||||
|       hook = raw.theme.extensionsHook; | ||||
|       raw.theme.extensionsHook = undefined; | ||||
|     } | ||||
|     this.theme = resolveTheme(mergeObjects({} as any, defaultTheme, raw.theme || {})); | ||||
|     this.theme.extensionsHook = hook; | ||||
| 
 | ||||
|     this.scrollYOffset = RedocNormalizedOptions.normalizeScrollYOffset(raw.scrollYOffset); | ||||
|     this.hideHostname = RedocNormalizedOptions.normalizeHideHostname(raw.hideHostname); | ||||
|     this.expandResponses = RedocNormalizedOptions.normalizeExpandResponses(raw.expandResponses); | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| import { ComponentClass, StatelessComponent } from 'react'; | ||||
| import * as styledComponents from 'styled-components'; | ||||
| 
 | ||||
| import { ResolvedThemeInterface } from './theme'; | ||||
| import { ResolvedThemeInterface, ThemeInterface } from './theme'; | ||||
| 
 | ||||
| export { ResolvedThemeInterface }; | ||||
| 
 | ||||
|  | @ -56,3 +56,12 @@ export const media = { | |||
| export { css, injectGlobal, keyframes, ThemeProvider, withProps }; | ||||
| export { StyledComponentClass } from 'styled-components'; | ||||
| export default styled; | ||||
| 
 | ||||
| export function extensionsHook(styledName: string) { | ||||
|   return props => { | ||||
|     if (!props.theme.extensionsHook) { | ||||
|       return; | ||||
|     } | ||||
|     return props.theme.extensionsHook(styledName, props); | ||||
|   }; | ||||
| } | ||||
|  |  | |||
|  | @ -2,6 +2,7 @@ import { adjustHue, desaturate, lighten, transparentize } from 'polished'; | |||
| 
 | ||||
| const defaultTheme: ThemeInterface = { | ||||
|   spacingUnit: 20, | ||||
| 
 | ||||
|   breakpoints: { | ||||
|     small: '50rem', | ||||
|     medium: '85rem', | ||||
|  | @ -74,6 +75,7 @@ const defaultTheme: ThemeInterface = { | |||
|   rightPanel: { | ||||
|     backgroundColor: '#263238', | ||||
|     width: '40%', | ||||
|     textColor: '#ffffff', | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
|  | @ -187,7 +189,10 @@ export interface ResolvedThemeInterface { | |||
|   rightPanel: { | ||||
|     backgroundColor: string; | ||||
|     width: string; | ||||
|     textColor: string; | ||||
|   }; | ||||
| 
 | ||||
|   extensionsHook?: (name: string, props: any) => string; | ||||
| } | ||||
| 
 | ||||
| export type primitive = string | number | boolean | undefined | null; | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user