redoc/src/theme.ts

346 lines
8.6 KiB
TypeScript
Raw Normal View History

2018-07-19 13:05:53 +03:00
import { darken, desaturate, lighten, readableColor, transparentize } from 'polished';
2018-03-16 18:02:31 +03:00
2018-03-17 00:58:25 +03:00
const defaultTheme: ThemeInterface = {
2018-07-19 13:05:53 +03:00
spacing: {
unit: 5,
sectionHorizontal: ({ spacing }) => spacing.unit * 8,
sectionVertical: ({ spacing }) => spacing.unit * 8,
2018-07-19 13:05:53 +03:00
},
2018-01-30 16:35:18 +03:00
breakpoints: {
small: '50rem',
medium: '75rem',
2018-01-30 16:35:18 +03:00
large: '105rem',
},
2017-10-12 00:01:37 +03:00
colors: {
2018-07-19 13:05:53 +03:00
tonalOffset: 0.3,
primary: {
main: '#32329f',
light: ({ colors }) => lighten(colors.tonalOffset, colors.primary.main),
dark: ({ colors }) => darken(colors.tonalOffset, colors.primary.main),
contrastText: ({ colors }) => readableColor(colors.primary.main),
},
success: {
main: '#1d8127',
light: ({ colors }) => lighten(colors.tonalOffset * 2, colors.success.main),
2018-07-19 13:05:53 +03:00
dark: ({ colors }) => darken(colors.tonalOffset, colors.success.main),
contrastText: ({ colors }) => readableColor(colors.success.main),
},
warning: {
main: '#ffa500',
2018-07-19 13:05:53 +03:00
light: ({ colors }) => lighten(colors.tonalOffset, colors.warning.main),
dark: ({ colors }) => darken(colors.tonalOffset, colors.warning.main),
contrastText: '#ffffff',
2018-07-19 13:05:53 +03:00
},
error: {
main: '#d41f1c',
2018-07-19 13:05:53 +03:00
light: ({ colors }) => lighten(colors.tonalOffset, colors.error.main),
dark: ({ colors }) => darken(colors.tonalOffset, colors.error.main),
contrastText: ({ colors }) => readableColor(colors.error.main),
},
gray: {
50: '#FAFAFA',
100: '#F5F5F5',
},
2018-07-19 13:05:53 +03:00
text: {
primary: '#333333',
secondary: ({ colors }) => lighten(colors.tonalOffset, colors.text.primary),
},
border: {
dark: 'rgba(0,0,0, 0.1)',
light: '#ffffff',
},
responses: {
success: {
color: ({ colors }) => colors.success.main,
backgroundColor: ({ colors }) => transparentize(0.93, colors.success.main),
2018-07-19 13:05:53 +03:00
},
error: {
color: ({ colors }) => colors.error.main,
backgroundColor: ({ colors }) => transparentize(0.93, colors.error.main),
2018-07-19 13:05:53 +03:00
},
redirect: {
color: ({ colors }) => colors.warning.main,
2018-07-19 13:05:53 +03:00
backgroundColor: ({ colors }) => transparentize(0.9, colors.responses.redirect.color),
},
info: {
color: '#87ceeb',
backgroundColor: ({ colors }) => transparentize(0.9, colors.responses.info.color),
},
},
2017-10-12 00:01:37 +03:00
http: {
get: '#6bbd5b',
post: '#248fb2',
put: '#9b708b',
options: '#d3ca12',
patch: '#e09d43',
delete: '#e27a7a',
basic: '#999',
link: '#31bbb6',
head: '#c167e4',
2017-10-12 00:01:37 +03:00
},
},
2018-07-19 13:05:53 +03:00
schema: {
linesColor: theme =>
lighten(
theme.colors.tonalOffset,
desaturate(theme.colors.tonalOffset, theme.colors.primary.main),
),
defaultDetailsWidth: '75%',
2018-07-19 13:05:53 +03:00
typeNameColor: theme => theme.colors.text.secondary,
typeTitleColor: theme => theme.schema.typeNameColor,
requireLabelColor: theme => theme.colors.error.main,
labelsTextSize: '0.9em',
2018-05-28 21:45:34 +03:00
nestingSpacing: '1em',
2018-07-19 13:05:53 +03:00
nestedBackground: '#fafafa',
arrow: {
size: '1.1em',
color: theme => theme.colors.text.secondary,
},
2017-10-12 00:01:37 +03:00
},
2018-07-19 13:05:53 +03:00
typography: {
fontSize: '14px',
lineHeight: '1.5em',
2018-07-19 13:05:53 +03:00
fontWeightRegular: '400',
fontWeightBold: '600',
fontWeightLight: '300',
fontFamily: 'Roboto, sans-serif',
2017-10-12 00:01:37 +03:00
smoothing: 'antialiased',
optimizeSpeed: true,
2018-07-19 13:05:53 +03:00
headings: {
fontFamily: 'Montserrat, sans-serif',
fontWeight: '400',
lineHeight: '1.6em',
2018-07-19 13:05:53 +03:00
},
code: {
fontSize: '13px',
fontFamily: 'Courier, monospace',
lineHeight: ({ typography }) => typography.lineHeight,
fontWeight: ({ typography }) => typography.fontWeightRegular,
color: '#e53935',
backgroundColor: 'rgba(38, 50, 56, 0.05)',
wrap: false,
2018-07-19 13:05:53 +03:00
},
links: {
color: ({ colors }) => colors.primary.main,
visited: ({ typography }) => typography.links.color,
hover: ({ typography }) => lighten(0.2, typography.links.color),
2018-07-19 13:05:53 +03:00
},
2017-10-12 00:01:37 +03:00
},
sidebar: {
2017-10-12 00:01:37 +03:00
width: '260px',
backgroundColor: '#fafafa',
textColor: '#333333',
2019-12-13 12:29:12 +03:00
activeTextColor: theme =>
theme.sidebar.textColor !== defaultTheme.sidebar!.textColor
? theme.sidebar.textColor
2019-12-13 12:29:12 +03:00
: theme.colors.primary.main,
groupItems: {
textTransform: 'uppercase',
},
level1Items: {
textTransform: 'none',
},
2018-07-19 13:05:53 +03:00
arrow: {
size: '1.5em',
color: theme => theme.sidebar.textColor,
2018-07-19 13:05:53 +03:00
},
2017-10-12 00:01:37 +03:00
},
logo: {
2020-07-25 18:42:35 +03:00
maxHeight: ({ sidebar }) => sidebar.width,
maxWidth: ({ sidebar }) => sidebar.width,
2019-04-08 17:42:30 +03:00
gutter: '2px',
2017-10-12 00:01:37 +03:00
},
rightPanel: {
backgroundColor: '#263238',
2018-03-16 18:02:31 +03:00
width: '40%',
2018-06-29 23:49:53 +03:00
textColor: '#ffffff',
2017-10-12 00:01:37 +03:00
},
codeBlock: {
backgroundColor: ({ rightPanel }) => darken(0.1, rightPanel.backgroundColor),
},
2017-10-12 00:01:37 +03:00
};
2018-03-17 00:58:25 +03:00
export default defaultTheme;
2017-10-12 00:01:37 +03:00
2018-03-16 18:02:31 +03:00
export function resolveTheme(theme: ThemeInterface): ResolvedThemeInterface {
const resolvedValues = {};
let counter = 0;
const setProxy = (obj, path: string) => {
Object.keys(obj).forEach(k => {
const currentPath = (path ? path + '.' : '') + k;
const val = obj[k];
if (typeof val === 'function') {
Object.defineProperty(obj, k, {
get() {
if (!resolvedValues[currentPath]) {
counter++;
if (counter > 1000) {
throw new Error(
`Theme probably contains circular dependency at ${currentPath}: ${val.toString()}`,
2018-03-16 18:02:31 +03:00
);
}
resolvedValues[currentPath] = val(theme);
}
return resolvedValues[currentPath];
},
enumerable: true,
});
} else if (typeof val === 'object') {
setProxy(val, currentPath);
}
});
};
setProxy(theme, '');
return JSON.parse(JSON.stringify(theme));
}
2018-07-19 13:05:53 +03:00
export interface ColorSetting {
main: string;
light: string;
dark: string;
contrastText: string;
}
export interface HTTPResponseColos {
color: string;
backgroundColor: string;
}
export interface FontSettings {
fontSize: string;
fontWeight: string;
fontFamily: string;
lineHeight: string;
color: string;
}
2018-03-16 18:02:31 +03:00
export interface ResolvedThemeInterface {
2018-07-19 13:05:53 +03:00
spacing: {
unit: number;
sectionHorizontal: number;
sectionVertical: number;
2018-07-19 13:05:53 +03:00
};
2018-03-16 18:02:31 +03:00
breakpoints: {
small: string;
medium: string;
large: string;
};
colors: {
2018-07-19 13:05:53 +03:00
tonalOffset: number;
primary: ColorSetting;
success: ColorSetting;
warning: ColorSetting;
error: ColorSetting;
gray: {
50: string;
100: string;
};
2018-07-19 13:05:53 +03:00
border: {
light: string;
dark: string;
};
text: {
primary: string;
secondary: string;
};
responses: {
success: HTTPResponseColos;
error: HTTPResponseColos;
redirect: HTTPResponseColos;
info: HTTPResponseColos;
};
2018-03-16 18:02:31 +03:00
http: {
get: string;
post: string;
put: string;
options: string;
patch: string;
delete: string;
basic: string;
link: string;
head: string;
2018-03-16 18:02:31 +03:00
};
};
2018-07-19 13:05:53 +03:00
schema: {
2018-03-16 18:02:31 +03:00
linesColor: string;
defaultDetailsWidth: string;
2018-03-20 17:15:36 +03:00
typeNameColor: string;
typeTitleColor: string;
requireLabelColor: string;
2018-07-19 13:05:53 +03:00
labelsTextSize: string;
2018-05-28 21:45:34 +03:00
nestingSpacing: string;
2018-07-19 13:05:53 +03:00
nestedBackground: string;
arrow: {
size: string;
color: string;
};
2018-03-16 18:02:31 +03:00
};
2018-07-19 13:05:53 +03:00
typography: {
fontSize: string;
2018-03-16 18:02:31 +03:00
lineHeight: string;
2018-07-19 13:05:53 +03:00
fontWeightLight: string;
fontWeightRegular: string;
fontWeightBold: string;
fontFamily: string;
2018-03-16 18:02:31 +03:00
smoothing: string;
optimizeSpeed: boolean;
2018-07-19 13:05:53 +03:00
code: FontSettings & {
backgroundColor: string;
wrap: boolean;
2018-07-19 13:05:53 +03:00
};
headings: {
fontFamily: string;
fontWeight: string;
lineHeight: string;
2018-07-19 13:05:53 +03:00
};
links: {
color: string;
visited: string;
hover: string;
};
2018-03-16 18:02:31 +03:00
};
sidebar: {
2018-03-16 18:02:31 +03:00
width: string;
backgroundColor: string;
textColor: string;
2019-12-13 12:29:12 +03:00
activeTextColor: string;
groupItems: {
textTransform: string;
};
level1Items: {
textTransform: string;
};
2018-07-19 13:05:53 +03:00
arrow: {
size: string;
color: string;
};
2018-03-16 18:02:31 +03:00
};
logo: {
maxHeight: string;
2018-03-22 19:22:11 +03:00
maxWidth: string;
2019-04-08 17:42:30 +03:00
gutter: string;
2018-03-16 18:02:31 +03:00
};
rightPanel: {
backgroundColor: string;
2018-06-29 23:49:53 +03:00
textColor: string;
2018-07-19 13:05:53 +03:00
width: string;
2018-03-16 18:02:31 +03:00
};
codeBlock: {
backgroundColor: string;
};
2018-06-29 23:49:53 +03:00
extensionsHook?: (name: string, props: any) => string;
2018-03-16 18:02:31 +03:00
}
export type primitive = string | number | boolean | undefined | null;
export type AdvancedThemeDeep<T> = T extends primitive
? T | ((theme: ResolvedThemeInterface) => T)
: AdvancedThemeObject<T>;
2018-05-28 21:45:34 +03:00
export type AdvancedThemeObject<T> = { [P in keyof T]?: AdvancedThemeDeep<T[P]> };
2018-03-16 18:02:31 +03:00
export type ThemeInterface = AdvancedThemeObject<ResolvedThemeInterface>;