redoc/src/theme.ts

187 lines
4.3 KiB
TypeScript
Raw Normal View History

2018-03-20 17:15:36 +03:00
import { adjustHue, desaturate, lighten, transparentize } from 'polished';
2018-03-16 18:02:31 +03:00
2018-03-17 00:58:25 +03:00
const defaultTheme: ThemeInterface = {
2017-10-12 00:01:37 +03:00
spacingUnit: 20,
2018-01-30 16:35:18 +03:00
breakpoints: {
small: '50rem',
medium: '85rem',
large: '105rem',
},
2017-10-12 00:01:37 +03:00
colors: {
main: '#32329f',
success: '#00aa13',
2018-03-16 18:02:31 +03:00
redirect: '#ffa500',
2017-10-12 00:01:37 +03:00
error: '#e53935',
2018-03-16 18:02:31 +03:00
info: '#87ceeb',
2017-10-12 00:01:37 +03:00
text: '#263238',
code: '#e53935',
codeBg: 'rgba(38, 50, 56, 0.04)',
2017-10-12 00:01:37 +03:00
warning: '#f1c400',
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
},
},
schemaView: {
2018-03-20 12:17:59 +03:00
linesColor: theme => lighten(0.25, desaturate(0.35, theme.colors.main)),
defaultDetailsWidth: '75%',
typeNameColor: theme => transparentize(0.2, theme.colors.text),
2018-03-20 17:15:36 +03:00
typeTitleColor: theme => theme.schemaView.typeNameColor,
requireLabelColor: theme => theme.colors.error,
2018-05-28 21:45:34 +03:00
nestingSpacing: '1em',
2017-10-12 00:01:37 +03:00
},
baseFont: {
size: '14px',
lineHeight: '1.5',
2018-06-26 09:36:32 +03:00
weight: '400',
2017-10-12 00:01:37 +03:00
family: 'Roboto, sans-serif',
smoothing: 'antialiased',
optimizeSpeed: true,
},
headingsFont: {
family: 'Montserrat, sans-serif',
},
code: {
fontSize: '13px',
2018-01-21 22:36:37 +03:00
fontFamily: 'Courier, monospace',
2017-10-12 00:01:37 +03:00
},
links: {
2018-03-16 18:02:31 +03:00
color: ({ colors }) => colors.main,
visited: ({ colors }) => colors.main,
hover: ({ colors }) => lighten(0.2, colors.main),
2017-10-12 00:01:37 +03:00
},
menu: {
width: '260px',
backgroundColor: '#fafafa',
},
logo: {
2018-03-22 19:22:11 +03:00
maxHeight: ({ menu }) => menu.width,
maxWidth: ({ menu }) => menu.width,
2017-10-12 00:01:37 +03:00
},
rightPanel: {
backgroundColor: '#263238',
2018-03-16 18:02:31 +03:00
width: '40%',
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 cirucal dependency at ${currentPath}: ${val.toString()}`,
);
}
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));
}
export interface ResolvedThemeInterface {
spacingUnit: number;
breakpoints: {
small: string;
medium: string;
large: string;
};
colors: {
main: string;
success: string;
redirect: string;
error: string;
info: string;
text: string;
code: string;
codeBg: string;
2018-03-16 18:02:31 +03:00
warning: string;
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
};
};
schemaView: {
linesColor: string;
defaultDetailsWidth: string;
2018-03-20 17:15:36 +03:00
typeNameColor: string;
typeTitleColor: string;
requireLabelColor: string;
2018-05-28 21:45:34 +03:00
nestingSpacing: string;
2018-03-16 18:02:31 +03:00
};
baseFont: {
size: string;
lineHeight: string;
weight: string;
family: string;
smoothing: string;
optimizeSpeed: boolean;
};
headingsFont: {
family: string;
};
code: {
fontSize: string;
fontFamily: string;
};
links: {
color: string;
visited: string;
hover: string;
};
menu: {
width: string;
backgroundColor: string;
};
logo: {
maxHeight: string;
2018-03-22 19:22:11 +03:00
maxWidth: string;
2018-03-16 18:02:31 +03:00
};
rightPanel: {
backgroundColor: string;
width: string;
};
}
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>;