feat: theme hooks experimental hooks

This commit is contained in:
Roman Hotsiy 2018-06-29 23:49:53 +03:00
parent b2c3c00e8c
commit 55bd8535b4
No known key found for this signature in database
GPG Key ID: 5CB7B3ACABA57CB0
11 changed files with 91 additions and 35 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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