diff --git a/src/common-elements/fields-layout.ts b/src/common-elements/fields-layout.ts
index 14b5f1d776..a1a24cd2bf 100644
--- a/src/common-elements/fields-layout.ts
+++ b/src/common-elements/fields-layout.ts
@@ -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`
diff --git a/src/common-elements/headers.ts b/src/common-elements/headers.ts
index 4797b2d3e7..96a64aa0cb 100644
--- a/src/common-elements/headers.ts
+++ b/src/common-elements/headers.ts
@@ -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')};
`;
diff --git a/src/components/ApiInfo/ApiInfo.tsx b/src/components/ApiInfo/ApiInfo.tsx
index 683dd5288d..e7058a8ae9 100644
--- a/src/components/ApiInfo/ApiInfo.tsx
+++ b/src/components/ApiInfo/ApiInfo.tsx
@@ -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 {
)}
+
+ {((info.license || info.contact || info.termsOfService) && (
+
+
+ {email} {website} {license} {terms}
+
+
+ )) ||
+ null}
- {((info.license || info.contact || info.termsOfService) && (
-
-
- {email} {website} {license} {terms}
-
-
- )) ||
- null}
-
- {(externalDocs && (
-
- {externalDocs.description || externalDocs.url}
-
- )) ||
- null}
+ {(externalDocs && (
+
+ {externalDocs.description || externalDocs.url}
+
+ )) ||
+ null}
+
);
diff --git a/src/components/ApiInfo/styled.elements.ts b/src/components/ApiInfo/styled.elements.ts
index 7852821fd9..583ff9f59e 100644
--- a/src/components/ApiInfo/styled.elements.ts
+++ b/src/components/ApiInfo/styled.elements.ts
@@ -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`
diff --git a/src/components/Markdown/styled.elements.ts b/src/components/Markdown/styled.elements.ts
index 2e94b65d6c..ff743c2b04 100644
--- a/src/components/Markdown/styled.elements.ts
+++ b/src/components/Markdown/styled.elements.ts
@@ -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};
+ }
+ }
`;
diff --git a/src/components/Redoc/styled.elements.tsx b/src/components/Redoc/styled.elements.tsx
index 4963a13d1a..1716cacb20 100644
--- a/src/components/Redoc/styled.elements.tsx
+++ b/src/components/Redoc/styled.elements.tsx
@@ -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`
diff --git a/src/components/RequestSamples/RequestSamples.tsx b/src/components/RequestSamples/RequestSamples.tsx
index d895dc41a8..d8d74dcd6f 100644
--- a/src/components/RequestSamples/RequestSamples.tsx
+++ b/src/components/RequestSamples/RequestSamples.tsx
@@ -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 {
return (
(hasSamples && (
-
Request samples
+
Request samples
diff --git a/src/components/ResponseSamples/ResponseSamples.tsx b/src/components/ResponseSamples/ResponseSamples.tsx
index 54f04baa62..aba643954d 100644
--- a/src/components/ResponseSamples/ResponseSamples.tsx
+++ b/src/components/ResponseSamples/ResponseSamples.tsx
@@ -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 {
return (
(responses.length > 0 && (
-
Response samples
+ Response samples
diff --git a/src/services/RedocNormalizedOptions.ts b/src/services/RedocNormalizedOptions.ts
index f1a7373ce3..f5f65505b4 100644
--- a/src/services/RedocNormalizedOptions.ts
+++ b/src/services/RedocNormalizedOptions.ts
@@ -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);
diff --git a/src/styled-components.ts b/src/styled-components.ts
index a9dee9a9fe..74466f4225 100644
--- a/src/styled-components.ts
+++ b/src/styled-components.ts
@@ -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);
+ };
+}
diff --git a/src/theme.ts b/src/theme.ts
index 526c69b54c..ffefc3d28c 100644
--- a/src/theme.ts
+++ b/src/theme.ts
@@ -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;