mirror of
https://github.com/Redocly/redoc.git
synced 2025-08-07 21:54:53 +03:00
feat: add theme support to additional elements
* H2 and H3 now use `theme.colors.primary.main` * The right panel allows controlling * Selected tab background and text colors * Endpoint background and text colors * Endpoint server background and text colors
This commit is contained in:
parent
3ae069c436
commit
3c3d5326bb
|
@ -6,7 +6,7 @@ const headerFontSize = {
|
|||
3: '1.27em',
|
||||
};
|
||||
|
||||
export const headerCommonMixin = level => css`
|
||||
export const headerCommonMixin = (level) => css`
|
||||
font-family: ${({ theme }) => theme.typography.headings.fontFamily};
|
||||
font-weight: ${({ theme }) => theme.typography.headings.fontWeight};
|
||||
font-size: ${headerFontSize[level]};
|
||||
|
@ -22,14 +22,14 @@ export const H1 = styled.h1`
|
|||
|
||||
export const H2 = styled.h2`
|
||||
${headerCommonMixin(2)};
|
||||
color: black;
|
||||
color: ${({ theme }) => theme.colors.primary.main};
|
||||
|
||||
${extensionsHook('H2')};
|
||||
`;
|
||||
|
||||
export const H3 = styled.h2`
|
||||
${headerCommonMixin(3)};
|
||||
color: black;
|
||||
color: ${({ theme }) => theme.colors.primary.main};
|
||||
|
||||
${extensionsHook('H3')};
|
||||
`;
|
||||
|
|
|
@ -31,8 +31,8 @@ export const Tabs = styled(ReactTabs)`
|
|||
font-weight: bold;
|
||||
|
||||
&.react-tabs__tab--selected {
|
||||
color: ${props => props.theme.colors.text.primary};
|
||||
background: ${({ theme }) => theme.rightPanel.textColor};
|
||||
color: ${(props) => props.theme.rightPanel.tabs.selectedTextColor};
|
||||
background: ${({ theme }) => theme.rightPanel.tabs.selectedBackgroundColor};
|
||||
&:focus {
|
||||
outline: auto;
|
||||
}
|
||||
|
@ -44,19 +44,19 @@ export const Tabs = styled(ReactTabs)`
|
|||
}
|
||||
|
||||
&.tab-success {
|
||||
color: ${props => props.theme.colors.responses.success.color};
|
||||
color: ${(props) => props.theme.colors.responses.success.color};
|
||||
}
|
||||
|
||||
&.tab-redirect {
|
||||
color: ${props => props.theme.colors.responses.redirect.color};
|
||||
color: ${(props) => props.theme.colors.responses.redirect.color};
|
||||
}
|
||||
|
||||
&.tab-info {
|
||||
color: ${props => props.theme.colors.responses.info.color};
|
||||
color: ${(props) => props.theme.colors.responses.info.color};
|
||||
}
|
||||
|
||||
&.tab-error {
|
||||
color: ${props => props.theme.colors.responses.error.color};
|
||||
color: ${(props) => props.theme.colors.responses.error.color};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ export const Tabs = styled(ReactTabs)`
|
|||
background: ${({ theme }) => theme.codeBlock.backgroundColor};
|
||||
& > div,
|
||||
& > pre {
|
||||
padding: ${props => props.theme.spacing.unit * 4}px;
|
||||
padding: ${(props) => props.theme.spacing.unit * 4}px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
|
@ -101,7 +101,7 @@ export const SmallTabs = styled(Tabs)`
|
|||
> .react-tabs__tab-panel {
|
||||
& > div,
|
||||
& > pre {
|
||||
padding: ${props => props.theme.spacing.unit * 2}px 0;
|
||||
padding: ${(props) => props.theme.spacing.unit * 2}px 0;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
|
|
@ -7,7 +7,7 @@ export const OperationEndpointWrap = styled.div`
|
|||
`;
|
||||
|
||||
export const ServerRelativeURL = styled.span`
|
||||
font-family: ${props => props.theme.typography.code.fontFamily};
|
||||
font-family: ${(props) => props.theme.typography.code.fontFamily};
|
||||
margin-left: 10px;
|
||||
flex: 1;
|
||||
overflow-x: hidden;
|
||||
|
@ -20,22 +20,22 @@ export const EndpointInfo = styled.button<{ expanded?: boolean; inverted?: boole
|
|||
width: 100%;
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
padding: 10px 30px 10px ${props => (props.inverted ? '10px' : '20px')};
|
||||
border-radius: ${props => (props.inverted ? '0' : '4px 4px 0 0')};
|
||||
background-color: ${props =>
|
||||
padding: 10px 30px 10px ${(props) => (props.inverted ? '10px' : '20px')};
|
||||
border-radius: ${(props) => (props.inverted ? '0' : '4px 4px 0 0')};
|
||||
background-color: ${(props) =>
|
||||
props.inverted ? 'transparent' : props.theme.codeBlock.backgroundColor};
|
||||
display: flex;
|
||||
white-space: nowrap;
|
||||
align-items: center;
|
||||
border: ${props => (props.inverted ? '0' : '1px solid transparent')};
|
||||
border-bottom: ${props => (props.inverted ? '1px solid #ccc' : '0')};
|
||||
border: ${(props) => (props.inverted ? '0' : '1px solid transparent')};
|
||||
border-bottom: ${(props) => (props.inverted ? '1px solid #ccc' : '0')};
|
||||
transition: border-color 0.25s ease;
|
||||
|
||||
${props =>
|
||||
${(props) =>
|
||||
(props.expanded && !props.inverted && `border-color: ${props.theme.colors.border.dark};`) || ''}
|
||||
|
||||
.${ServerRelativeURL} {
|
||||
color: ${props => (props.inverted ? props.theme.colors.text.primary : '#ffffff')}
|
||||
color: ${(props) => (props.inverted ? props.theme.colors.text.primary : '#ffffff')}
|
||||
}
|
||||
&:focus {
|
||||
box-shadow: inset 0 2px 2px rgba(0, 0, 0, 0.45), 0 2px 0 rgba(128, 128, 128, 0.25);
|
||||
|
@ -45,13 +45,13 @@ export const EndpointInfo = styled.button<{ expanded?: boolean; inverted?: boole
|
|||
export const HttpVerb = styled.span.attrs((props: { type: string; compact?: boolean }) => ({
|
||||
className: `http-verb ${props.type}`,
|
||||
}))<{ type: string; compact?: boolean }>`
|
||||
font-size: ${props => (props.compact ? '0.8em' : '0.929em')};
|
||||
line-height: ${props => (props.compact ? '18px' : '20px')};
|
||||
background-color: ${props => props.theme.colors.http[props.type] || '#999999'};
|
||||
font-size: ${(props) => (props.compact ? '0.8em' : '0.929em')};
|
||||
line-height: ${(props) => (props.compact ? '18px' : '20px')};
|
||||
background-color: ${(props) => props.theme.colors.http[props.type] || '#999999'};
|
||||
color: #ffffff;
|
||||
padding: ${props => (props.compact ? '2px 8px' : '3px 10px')};
|
||||
padding: ${(props) => (props.compact ? '2px 8px' : '3px 10px')};
|
||||
text-transform: uppercase;
|
||||
font-family: ${props => props.theme.typography.headings.fontFamily};
|
||||
font-family: ${(props) => props.theme.typography.headings.fontFamily};
|
||||
margin: 0;
|
||||
`;
|
||||
|
||||
|
@ -59,8 +59,8 @@ export const ServersOverlay = styled.div<{ expanded: boolean }>`
|
|||
position: absolute;
|
||||
width: 100%;
|
||||
z-index: 100;
|
||||
background: #fafafa;
|
||||
color: #263238;
|
||||
background: ${(props) => props.theme.rightPanel.endpoint.backgroundColor};
|
||||
color: ${(props) => props.theme.rightPanel.endpoint.textColor};
|
||||
box-sizing: border-box;
|
||||
box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.33);
|
||||
overflow: hidden;
|
||||
|
@ -68,7 +68,7 @@ export const ServersOverlay = styled.div<{ expanded: boolean }>`
|
|||
border-bottom-right-radius: 4px;
|
||||
transition: all 0.25s ease;
|
||||
visibility: hidden;
|
||||
${props => (props.expanded ? 'visibility: visible;' : 'transform: translateY(-50%) scaleY(0);')}
|
||||
${(props) => (props.expanded ? 'visibility: visible;' : 'transform: translateY(-50%) scaleY(0);')}
|
||||
`;
|
||||
|
||||
export const ServerItem = styled.div`
|
||||
|
@ -78,10 +78,10 @@ export const ServerItem = styled.div`
|
|||
export const ServerUrl = styled.div`
|
||||
padding: 5px;
|
||||
border: 1px solid #ccc;
|
||||
background: #fff;
|
||||
background: ${(props) => props.theme.rightPanel.endpoint.serverBackgroundColor};
|
||||
word-break: break-all;
|
||||
color: ${props => props.theme.colors.primary.main};
|
||||
color: ${(props) => props.theme.rightPanel.endpoint.serverTextColor};
|
||||
> span {
|
||||
color: ${props => props.theme.colors.text.primary};
|
||||
color: ${(props) => props.theme.rightPanel.endpoint.serverTextColor};
|
||||
}
|
||||
`;
|
||||
|
|
36
src/theme.ts
36
src/theme.ts
|
@ -80,21 +80,21 @@ const defaultTheme: ThemeInterface = {
|
|||
},
|
||||
},
|
||||
schema: {
|
||||
linesColor: theme =>
|
||||
linesColor: (theme) =>
|
||||
lighten(
|
||||
theme.colors.tonalOffset,
|
||||
desaturate(theme.colors.tonalOffset, theme.colors.primary.main),
|
||||
),
|
||||
defaultDetailsWidth: '75%',
|
||||
typeNameColor: theme => theme.colors.text.secondary,
|
||||
typeTitleColor: theme => theme.schema.typeNameColor,
|
||||
requireLabelColor: theme => theme.colors.error.main,
|
||||
typeNameColor: (theme) => theme.colors.text.secondary,
|
||||
typeTitleColor: (theme) => theme.schema.typeNameColor,
|
||||
requireLabelColor: (theme) => theme.colors.error.main,
|
||||
labelsTextSize: '0.9em',
|
||||
nestingSpacing: '1em',
|
||||
nestedBackground: '#fafafa',
|
||||
arrow: {
|
||||
size: '1.1em',
|
||||
color: theme => theme.colors.text.secondary,
|
||||
color: (theme) => theme.colors.text.secondary,
|
||||
},
|
||||
},
|
||||
typography: {
|
||||
|
@ -130,7 +130,7 @@ const defaultTheme: ThemeInterface = {
|
|||
width: '260px',
|
||||
backgroundColor: '#fafafa',
|
||||
textColor: '#333333',
|
||||
activeTextColor: theme =>
|
||||
activeTextColor: (theme) =>
|
||||
theme.sidebar.textColor !== defaultTheme.sidebar!.textColor
|
||||
? theme.sidebar.textColor
|
||||
: theme.colors.primary.main,
|
||||
|
@ -142,7 +142,7 @@ const defaultTheme: ThemeInterface = {
|
|||
},
|
||||
arrow: {
|
||||
size: '1.5em',
|
||||
color: theme => theme.sidebar.textColor,
|
||||
color: (theme) => theme.sidebar.textColor,
|
||||
},
|
||||
},
|
||||
logo: {
|
||||
|
@ -154,6 +154,16 @@ const defaultTheme: ThemeInterface = {
|
|||
backgroundColor: '#263238',
|
||||
width: '40%',
|
||||
textColor: '#ffffff',
|
||||
tabs: {
|
||||
selectedBackgroundColor: (theme) => theme.rightPanel.textColor,
|
||||
selectedTextColor: (theme) => theme.colors.text.primary,
|
||||
},
|
||||
endpoint: {
|
||||
backgroundColor: '#fafafa',
|
||||
textColor: (theme) => theme.colors.primary.main,
|
||||
serverBackgroundColor: '#ffffff',
|
||||
serverTextColor: (theme) => theme.colors.text.primary,
|
||||
},
|
||||
},
|
||||
codeBlock: {
|
||||
backgroundColor: ({ rightPanel }) => darken(0.1, rightPanel.backgroundColor),
|
||||
|
@ -166,7 +176,7 @@ export function resolveTheme(theme: ThemeInterface): ResolvedThemeInterface {
|
|||
const resolvedValues = {};
|
||||
let counter = 0;
|
||||
const setProxy = (obj, path: string) => {
|
||||
Object.keys(obj).forEach(k => {
|
||||
Object.keys(obj).forEach((k) => {
|
||||
const currentPath = (path ? path + '.' : '') + k;
|
||||
const val = obj[k];
|
||||
if (typeof val === 'function') {
|
||||
|
@ -329,6 +339,16 @@ export interface ResolvedThemeInterface {
|
|||
backgroundColor: string;
|
||||
textColor: string;
|
||||
width: string;
|
||||
tabs: {
|
||||
selectedBackgroundColor: string;
|
||||
selectedTextColor: string;
|
||||
};
|
||||
endpoint: {
|
||||
backgroundColor: string;
|
||||
textColor: string;
|
||||
serverBackgroundColor: string;
|
||||
serverTextColor: string;
|
||||
};
|
||||
};
|
||||
codeBlock: {
|
||||
backgroundColor: string;
|
||||
|
|
Loading…
Reference in New Issue
Block a user