DOP-3306: Modify Redoc with MongoDB styling (#1)

This commit is contained in:
rayangler 2022-12-07 10:54:16 -05:00 committed by GitHub
parent 8b09a07476
commit b3d531770b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 2978 additions and 1118 deletions

View File

@ -1,13 +1,7 @@
## What/Why/How? ### Stories/Links:
## Reference DOP-NNNN
## Testing ### Screenshots (optional):
## Screenshots (optional) ### Notes:
## Check yourself
- [ ] Code is linted
- [ ] Tested
- [ ] All new/updated code is covered with tests

View File

@ -5,6 +5,9 @@ on: [push]
jobs: jobs:
build-and-e2e: build-and-e2e:
runs-on: ubuntu-latest runs-on: ubuntu-latest
env:
NPM_BASE_64_AUTH: ${{ secrets.NPM_BASE_64_AUTH }}
NPM_EMAIL: ${{ secrets.NPM_EMAIL }}
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- run: npm ci && npm ci --prefix cli - run: npm ci && npm ci --prefix cli

View File

@ -5,6 +5,9 @@ on: [push]
jobs: jobs:
build-and-unit: build-and-unit:
runs-on: ubuntu-latest runs-on: ubuntu-latest
env:
NPM_BASE_64_AUTH: ${{ secrets.NPM_BASE_64_AUTH }}
NPM_EMAIL: ${{ secrets.NPM_EMAIL }}
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- run: npm ci && npm ci --prefix cli - run: npm ci && npm ci --prefix cli

4
.npmrc Normal file
View File

@ -0,0 +1,4 @@
registry=https://artifactory.corp.mongodb.com/artifactory/api/npm/npm/
_auth=${NPM_BASE_64_AUTH}
_email=${NPM_EMAIL}
_always-auth=true

1
.nvmrc Normal file
View File

@ -0,0 +1 @@
v14.17.6

View File

@ -11,6 +11,35 @@
**This is the README for the `2.x` version of Redoc (React-based).** **This is the README for the `2.x` version of Redoc (React-based).**
**The README for the `1.x` version is on the [v1.x](https://github.com/Redocly/redoc/tree/v1.x) branch.** **The README for the `1.x` version is on the [v1.x](https://github.com/Redocly/redoc/tree/v1.x) branch.**
## Forked Redoc
**This includes information about this fork of Redoc. Proceed to the next section for original information about Redoc.**
This is a fork of Redoc for the purpose of customizing the component for MongoDB documentation.
Both the CLI and React component are used for the team's build process for static site generation.
### Installation
Ensure [Artifactory](https://artifactory.corp.mongodb.com/ui/packages) credentials are set up and set to `NPM_BASE_64_AUTH` and `NPM_EMAIL` env variables. This should be similar to the setup on [Snooty](https://github.com/mongodb/snooty/#installation). Below are the instructions to work with Redoc locally with custom MongoDB components, such as the Consistent Nav:
1) In `redoc`/root folder of this fork, run `npm install`.
2) In `redoc/cli` folder, run `npm install`.
3) In `redoc/cli` folder, run: `npm link ../ ../node_modules/react/ ../node_modules/styled-components/`. This will link certain CLI dependencies to be compatible with the local instance and fork of Redoc.
- `../` is for `redoc`.
- `../node_modules/react/` is to fix React hook errors.
- `../node_modules/styled-components/` is to fix styling issues.
4) In `redoc`/root folder, run: `npm run bundle`. This will create bundled files needed by the CLI / needed to run the CLI.
### Running the CLI
Make sure to run `npm run bundle` on the root folder of this repo before running the CLI.
With `node` installed, run by doing the following:
```
node <path/to/redoc/cli/index.js> build <path/to/spec/file/or/url> --options=<path/to/options.json> --output=<path/to/custom/output/file/name.html>
```
## About Redoc ## About Redoc
Redoc is an open-source tool for generating documentation from OpenAPI (fka Swagger) definitions. Redoc is an open-source tool for generating documentation from OpenAPI (fka Swagger) definitions.

View File

@ -19,7 +19,7 @@ describe('build', () => {
try { try {
const redocStaticFile = readFileSync(`${__dirname}/redoc-test.html`, 'utf8'); const redocStaticFile = readFileSync(`${__dirname}/redoc-test.html`, 'utf8');
expect(redocStaticFile).toContain('"options":{"disableSearch":true}'); expect(redocStaticFile).toContain('"options":{"disableSearch":true}');
expect(redocStaticFile).not.toContain('role="search"'); expect(redocStaticFile).not.toContain('data-role="redoc-search"');
} catch (err) { } catch (err) {
expect(err.toString()).toContain('{"options":{"disableSearch":"true"}'); expect(err.toString()).toContain('{"options":{"disableSearch":"true"}');
} }

View File

@ -1,5 +1,5 @@
describe('Search', () => { describe('Search', () => {
const getSearchInput = () => cy.get('[role="search"] input'); const getSearchInput = () => cy.get('[data-role="redoc-search"] input');
const getSearchResults = () => cy.get('[data-role="search:results"]'); const getSearchResults = () => cy.get('[data-role="search:results"]');
const getResult = i => cy.get('[role=search] [role=menuitem]').eq(i); const getResult = i => cy.get('[role=search] [role=menuitem]').eq(i);

1732
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -141,6 +141,13 @@
"styled-components": "^4.1.1 || ^5.1.1" "styled-components": "^4.1.1 || ^5.1.1"
}, },
"dependencies": { "dependencies": {
"@emotion/css": "^11.0.0",
"@emotion/react": "^11.10.4",
"@emotion/styled": "^11.10.4",
"@leafygreen-ui/palette": "^3.4.4",
"@mdb/consistent-nav": "^1.2.16",
"@mdb/flora": "^0.20.5",
"@mdx-js/react": "^1.6.22",
"@redocly/openapi-core": "^1.0.0-beta.104", "@redocly/openapi-core": "^1.0.0-beta.104",
"classnames": "^2.3.1", "classnames": "^2.3.1",
"decko": "^1.2.0", "decko": "^1.2.0",
@ -162,6 +169,7 @@
"stickyfill": "^1.1.1", "stickyfill": "^1.1.1",
"style-loader": "^3.3.1", "style-loader": "^3.3.1",
"swagger2openapi": "^7.0.6", "swagger2openapi": "^7.0.6",
"theme-ui": "^0.13.1",
"url-template": "^2.0.8" "url-template": "^2.0.8"
}, },
"size-limit": [ "size-limit": [

View File

@ -1,3 +1,4 @@
import { palette } from '@leafygreen-ui/palette';
import styled from 'styled-components'; import styled from 'styled-components';
import { Dropdown as DropdownComponent } from './Dropdown'; import { Dropdown as DropdownComponent } from './Dropdown';
@ -38,6 +39,11 @@ export const Dropdown = styled(DropdownComponent)<{
color: ${({ theme }) => theme.colors.text.primary}; color: ${({ theme }) => theme.colors.text.primary};
line-height: inherit; line-height: inherit;
font-family: inherit; font-family: inherit;
background-color: ${palette.gray.dark2};
:hover {
background-color: ${palette.gray.dark2};
}
} }
box-sizing: border-box; box-sizing: border-box;
min-width: 100px; min-width: 100px;

View File

@ -1,3 +1,4 @@
import { palette } from '@leafygreen-ui/palette';
import styled, { extensionsHook } from '../styled-components'; import styled, { extensionsHook } from '../styled-components';
export const PrismDiv = styled.div` export const PrismDiv = styled.div`
@ -50,6 +51,7 @@ export const PrismDiv = styled.div`
.token.punctuation { .token.punctuation {
opacity: 0.7; opacity: 0.7;
color: ${palette.white};
} }
.namespace { .namespace {
@ -61,11 +63,11 @@ export const PrismDiv = styled.div`
.token.number, .token.number,
.token.constant, .token.constant,
.token.symbol { .token.symbol {
color: #4a8bb3; color: #2dc4ff;
} }
.token.boolean { .token.boolean {
color: #e64441; color: #ff6f44;
} }
.token.selector, .token.selector,
@ -90,13 +92,13 @@ export const PrismDiv = styled.div`
.token.entity, .token.entity,
.token.url, .token.url,
.token.variable { .token.variable {
color: hsl(40, 90%, 60%); color: #edb210;
} }
.token.atrule, .token.atrule,
.token.attr-value, .token.attr-value,
.token.keyword { .token.keyword {
color: hsl(350, 40%, 70%); color: #ff7dc3;
} }
.token.regex, .token.regex,
@ -120,5 +122,13 @@ export const PrismDiv = styled.div`
color: red; color: red;
} }
.token.string:not(.property) {
color: #35de7b;
}
.token.string-property {
color: #2dc4ff;
}
${extensionsHook('Prism')}; ${extensionsHook('Prism')};
`; `;

View File

@ -1,4 +1,5 @@
import { transparentize } from 'polished'; import { transparentize } from 'polished';
import { palette } from '@leafygreen-ui/palette';
import styled, { extensionsHook, css } from '../styled-components'; import styled, { extensionsHook, css } from '../styled-components';
import { PropertyNameCell } from './fields-layout'; import { PropertyNameCell } from './fields-layout';
@ -87,7 +88,7 @@ export const RecursiveLabel = styled(FieldLabel)`
`; `;
export const PatternLabel = styled(FieldLabel)` export const PatternLabel = styled(FieldLabel)`
color: #0e7c86; color: ${palette.gray.dark3};
&::before, &::before,
&::after { &::after {
font-weight: bold; font-weight: bold;
@ -98,11 +99,11 @@ export const ExampleValue = styled(FieldLabel)`
border-radius: 2px; border-radius: 2px;
word-break: break-word; word-break: break-word;
${({ theme }) => ` ${({ theme }) => `
background-color: ${transparentize(0.95, theme.colors.text.primary)}; background-color: ${palette.gray.light3};
color: ${transparentize(0.1, theme.colors.text.primary)}; color: ${palette.gray.dark3};
padding: 0 ${theme.spacing.unit}px; padding: 0 ${theme.spacing.unit}px;
border: 1px solid ${transparentize(0.9, theme.colors.text.primary)}; border: 1px solid ${palette.gray.light2};
font-family: ${theme.typography.code.fontFamily}; font-family: ${theme.typography.code.fontFamily};
}`}; }`};
& + & { & + & {
@ -116,12 +117,12 @@ export const ExtensionValue = styled(ExampleValue)``;
export const ConstraintItem = styled(FieldLabel)` export const ConstraintItem = styled(FieldLabel)`
border-radius: 2px; border-radius: 2px;
${({ theme }) => ` ${({ theme }) => `
background-color: ${transparentize(0.95, theme.colors.primary.light)}; background-color: ${palette.blue.light3};
color: ${transparentize(0.1, theme.colors.primary.main)}; color: ${palette.blue.base};
margin: 0 ${theme.spacing.unit}px; margin: 0 ${theme.spacing.unit}px;
padding: 0 ${theme.spacing.unit}px; padding: 0 ${theme.spacing.unit}px;
border: 1px solid ${transparentize(0.9, theme.colors.primary.main)}; border: 1px solid ${palette.blue.light2};
}`}; }`};
& + & { & + & {
margin-left: 0; margin-left: 0;

View File

@ -16,6 +16,9 @@ export const headerCommonMixin = level => css`
export const H1 = styled.h1` export const H1 = styled.h1`
${headerCommonMixin(1)}; ${headerCommonMixin(1)};
color: ${({ theme }) => theme.colors.text.primary}; color: ${({ theme }) => theme.colors.text.primary};
font-weight: 500;
font-size: 24px;
line-height: 32px;
${extensionsHook('H1')}; ${extensionsHook('H1')};
`; `;
@ -24,6 +27,9 @@ export const H2 = styled.h2`
${headerCommonMixin(2)}; ${headerCommonMixin(2)};
color: ${({ theme }) => theme.colors.text.primary}; color: ${({ theme }) => theme.colors.text.primary};
margin: 0 0 20px; margin: 0 0 20px;
font-weight: 600;
font-size: 18px;
line-height: 24px;
${extensionsHook('H2')}; ${extensionsHook('H2')};
`; `;

View File

@ -14,7 +14,7 @@ export const SampleControls = styled.div`
color: inherit; color: inherit;
padding: 2px 10px; padding: 2px 10px;
font-family: ${({ theme }) => theme.typography.fontFamily}; font-family: ${({ theme }) => theme.typography.fontFamily};
font-size: ${({ theme }) => theme.typography.fontSize}; font-size: 13px;
line-height: ${({ theme }) => theme.typography.lineHeight}; line-height: ${({ theme }) => theme.typography.lineHeight};
cursor: pointer; cursor: pointer;
outline: 0; outline: 0;

View File

@ -57,8 +57,9 @@ export const Badge = styled.span<{ type: string }>`
vertical-align: middle; vertical-align: middle;
line-height: 1.6; line-height: 1.6;
border-radius: 4px; border-radius: 4px;
font-weight: ${({ theme }) => theme.typography.fontWeightBold}; font-weight: ${({ theme, type }) =>
font-size: 12px; type === 'warning' ? 'normal' : theme.typography.fontWeightBold};
font-size: 13px;
+ span[type] { + span[type] {
margin-left: 4px; margin-left: 4px;
} }

View File

@ -1,3 +1,4 @@
import { palette } from '@leafygreen-ui/palette';
import { darken } from 'polished'; import { darken } from 'polished';
import { Tabs as ReactTabs } from 'react-tabs'; import { Tabs as ReactTabs } from 'react-tabs';
@ -16,26 +17,39 @@ export const Tabs = styled(ReactTabs)`
padding: 5px 10px; padding: 5px 10px;
display: inline-block; display: inline-block;
background-color: ${({ theme }) => theme.codeBlock.backgroundColor}; background-color: ${palette.gray.dark3};
border-bottom: 1px solid rgba(0, 0, 0, 0.5); border-bottom: 1px solid rgba(0, 0, 0, 0.5);
cursor: pointer; cursor: pointer;
text-align: center; text-align: center;
outline: none; outline: none;
color: ${({ theme }) => darken(theme.colors.tonalOffset, theme.rightPanel.textColor)}; color: ${palette.gray.base};
margin: 0 margin: 0
${({ theme }) => `${theme.spacing.unit}px ${theme.spacing.unit}px ${theme.spacing.unit}px`}; ${({ theme }) => `${theme.spacing.unit}px ${theme.spacing.unit}px ${theme.spacing.unit}px`};
border: 1px solid ${({ theme }) => darken(0.05, theme.codeBlock.backgroundColor)}; border: none;
border-radius: 5px; border-radius: 5px;
min-width: 60px; min-width: 60px;
font-size: 0.9em; font-size: 13px;
font-weight: bold; font-weight: bold;
&.react-tabs__tab--selected { &.react-tabs__tab--selected {
color: ${props => props.theme.colors.text.primary}; color: ${palette.white};
background: ${({ theme }) => theme.rightPanel.textColor}; background-color: ${palette.gray.dark2};
border: 1px solid ${palette.gray.base};
&:focus { &:focus {
outline: auto; outline: auto;
} }
&.tab-error {
background-color: ${palette.gray.dark2};
border: none;
color: ${palette.red.light1};
}
&.tab-success {
background-color: ${palette.gray.dark2};
border: none;
color: ${palette.green.light1};
}
} }
&:only-child { &:only-child {
@ -43,10 +57,6 @@ export const Tabs = styled(ReactTabs)`
min-width: 100px; min-width: 100px;
} }
&.tab-success {
color: ${props => props.theme.colors.responses.success.tabTextColor};
}
&.tab-redirect { &.tab-redirect {
color: ${props => props.theme.colors.responses.redirect.tabTextColor}; color: ${props => props.theme.colors.responses.redirect.tabTextColor};
} }
@ -54,10 +64,6 @@ export const Tabs = styled(ReactTabs)`
&.tab-info { &.tab-info {
color: ${props => props.theme.colors.responses.info.tabTextColor}; color: ${props => props.theme.colors.responses.info.tabTextColor};
} }
&.tab-error {
color: ${props => props.theme.colors.responses.error.tabTextColor};
}
} }
} }
> .react-tabs__tab-panel { > .react-tabs__tab-panel {

View File

@ -1,3 +1,4 @@
import { palette } from '@leafygreen-ui/palette';
import { H1, MiddlePanel } from '../../common-elements'; import { H1, MiddlePanel } from '../../common-elements';
import styled, { extensionsHook } from '../../styled-components'; import styled, { extensionsHook } from '../../styled-components';
@ -8,6 +9,11 @@ export const ApiInfoWrap = MiddlePanel;
export const ApiHeader = styled(H1)` export const ApiHeader = styled(H1)`
margin-top: 0; margin-top: 0;
margin-bottom: 0.5em; margin-bottom: 0.5em;
color: ${palette.green.dark2};
font-family: 'MongoDB Value Serif';
font-size: 32px;
font-weight: 400;
line-height: 40px;
${extensionsHook('ApiHeader')}; ${extensionsHook('ApiHeader')};
`; `;

View File

@ -1,4 +1,6 @@
import { palette } from '@leafygreen-ui/palette';
import styled from '../../styled-components'; import styled from '../../styled-components';
import { getBadgeStyles } from '../../utils/styling';
export const OperationEndpointWrap = styled.div` export const OperationEndpointWrap = styled.div`
cursor: pointer; cursor: pointer;
@ -22,8 +24,7 @@ export const EndpointInfo = styled.button<{ expanded?: boolean; inverted?: boole
cursor: pointer; cursor: pointer;
padding: 10px 30px 10px ${props => (props.inverted ? '10px' : '20px')}; padding: 10px 30px 10px ${props => (props.inverted ? '10px' : '20px')};
border-radius: ${props => (props.inverted ? '0' : '4px 4px 0 0')}; border-radius: ${props => (props.inverted ? '0' : '4px 4px 0 0')};
background-color: ${props => background-color: ${palette.gray.dark3};
props.inverted ? 'transparent' : props.theme.codeBlock.backgroundColor};
display: flex; display: flex;
white-space: nowrap; white-space: nowrap;
align-items: center; align-items: center;
@ -47,12 +48,15 @@ export const HttpVerb = styled.span.attrs((props: { type: string; compact?: bool
}))<{ type: string; compact?: boolean }>` }))<{ type: string; compact?: boolean }>`
font-size: ${props => (props.compact ? '0.8em' : '0.929em')}; font-size: ${props => (props.compact ? '0.8em' : '0.929em')};
line-height: ${props => (props.compact ? '18px' : '20px')}; line-height: ${props => (props.compact ? '18px' : '20px')};
background-color: ${props => props.theme.colors.http[props.type] || '#999999'};
color: #ffffff; color: #ffffff;
padding: ${props => (props.compact ? '2px 8px' : '3px 10px')}; padding: ${props => (props.compact ? '2px 8px' : '3px 10px')};
text-transform: uppercase; text-transform: uppercase;
font-family: ${props => props.theme.typography.headings.fontFamily}; font-family: ${props => props.theme.typography.headings.fontFamily};
font-weight: bold;
margin: 0; margin: 0;
border: ${props => props.theme.badges.border};
border-radius: ${props => props.theme.badges.borderRadius};
${props => getBadgeStyles(props.theme.colors.http[props.type], 'dark')}
`; `;
export const ServersOverlay = styled.div<{ expanded: boolean }>` export const ServersOverlay = styled.div<{ expanded: boolean }>`
@ -61,6 +65,7 @@ export const ServersOverlay = styled.div<{ expanded: boolean }>`
z-index: 100; z-index: 100;
background: ${props => props.theme.rightPanel.servers.overlay.backgroundColor}; background: ${props => props.theme.rightPanel.servers.overlay.backgroundColor};
color: ${props => props.theme.rightPanel.servers.overlay.textColor}; color: ${props => props.theme.rightPanel.servers.overlay.textColor};
font-size: 13px;
box-sizing: border-box; box-sizing: border-box;
box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.33); box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.33);
overflow: hidden; overflow: hidden;
@ -77,11 +82,13 @@ export const ServerItem = styled.div`
export const ServerUrl = styled.div` export const ServerUrl = styled.div`
padding: 5px; padding: 5px;
border: 1px solid #ccc; border: 1px solid ${palette.gray.dark2};
background: ${props => props.theme.rightPanel.servers.url.backgroundColor}; background: ${props => props.theme.rightPanel.servers.url.backgroundColor};
font-family: 'Source Code Pro';
font-size: 13px;
word-break: break-all; word-break: break-all;
color: ${props => props.theme.colors.primary.main}; color: ${palette.white};
> span { > span {
color: ${props => props.theme.colors.text.primary}; color: ${palette.white};
} }
`; `;

View File

@ -1,10 +1,11 @@
import { transparentize } from 'polished'; import { transparentize } from 'polished';
import styled from '../../styled-components'; import styled from '../../styled-components';
import { Dropdown } from '../../common-elements/Dropdown'; import { Dropdown } from '../../common-elements/Dropdown';
import { palette } from '@leafygreen-ui/palette';
export const MimeLabel = styled.div` export const MimeLabel = styled.div`
padding: 0.9em; padding: 0.9em;
background-color: ${({ theme }) => transparentize(0.6, theme.rightPanel.backgroundColor)}; background-color: ${palette.gray.dark2};
margin: 0 0 10px 0; margin: 0 0 10px 0;
display: block; display: block;
font-family: ${({ theme }) => theme.typography.headings.fontFamily}; font-family: ${({ theme }) => theme.typography.headings.fontFamily};
@ -24,7 +25,13 @@ export const DropdownLabel = styled.span`
`; `;
export const DropdownWrapper = styled.div` export const DropdownWrapper = styled.div`
background-color: ${palette.gray.dark2};
position: relative; position: relative;
font-size: 13px;
:hover {
background-color: ${palette.gray.dark2};
}
`; `;
export const InvertedSimpleDropdown = styled(Dropdown)` export const InvertedSimpleDropdown = styled(Dropdown)`
@ -39,7 +46,7 @@ export const InvertedSimpleDropdown = styled(Dropdown)`
} }
margin: 0 0 10px 0; margin: 0 0 10px 0;
display: block; display: block;
background-color: ${({ theme }) => transparentize(0.6, theme.rightPanel.backgroundColor)}; background-color: ${palette.gray.dark2};
border: none; border: none;
padding: 0.9em 1.6em 0.9em 0.9em; padding: 0.9em 1.6em 0.9em 0.9em;
box-shadow: none; box-shadow: none;
@ -47,7 +54,7 @@ export const InvertedSimpleDropdown = styled(Dropdown)`
&:focus-within { &:focus-within {
border: none; border: none;
box-shadow: none; box-shadow: none;
background-color: ${({ theme }) => transparentize(0.3, theme.rightPanel.backgroundColor)}; background-color: ${palette.gray.dark2};
} }
`; `;

View File

@ -1,5 +1,6 @@
import * as PropTypes from 'prop-types'; import * as PropTypes from 'prop-types';
import * as React from 'react'; import * as React from 'react';
import { UnifiedFooter, UnifiedNav } from '@mdb/consistent-nav';
import { ThemeProvider } from '../../styled-components'; import { ThemeProvider } from '../../styled-components';
import { OptionsProvider } from '../OptionsProvider'; import { OptionsProvider } from '../OptionsProvider';
@ -10,7 +11,13 @@ import { ApiLogo } from '../ApiLogo/ApiLogo';
import { ContentItems } from '../ContentItems/ContentItems'; import { ContentItems } from '../ContentItems/ContentItems';
import { SideMenu } from '../SideMenu/SideMenu'; import { SideMenu } from '../SideMenu/SideMenu';
import { StickyResponsiveSidebar } from '../StickySidebar/StickyResponsiveSidebar'; import { StickyResponsiveSidebar } from '../StickySidebar/StickyResponsiveSidebar';
import { ApiContentWrap, BackgroundStub, RedocWrap } from './styled.elements'; import {
ApiContentWrap,
BackgroundStub,
RedocWrap,
SideMenuTitle,
StyledHeader,
} from './styled.elements';
import { SearchBox } from '../SearchBox/SearchBox'; import { SearchBox } from '../SearchBox/SearchBox';
import { StoreProvider } from '../StoreBuilder'; import { StoreProvider } from '../StoreBuilder';
@ -37,13 +44,18 @@ export class Redoc extends React.Component<RedocProps> {
store: { spec, menu, options, search, marker }, store: { spec, menu, options, search, marker },
} = this.props; } = this.props;
const store = this.props.store; const store = this.props.store;
return ( return (
<ThemeProvider theme={options.theme}> <ThemeProvider theme={options.theme}>
<StoreProvider value={store}> <StoreProvider value={store}>
<OptionsProvider value={options}> <OptionsProvider value={options}>
<StyledHeader>
<UnifiedNav position="relative" property={{ name: 'DOCS', searchParams: [] }} />
</StyledHeader>
<RedocWrap className="redoc-wrap"> <RedocWrap className="redoc-wrap">
<StickyResponsiveSidebar menu={menu} className="menu-content"> <StickyResponsiveSidebar menu={menu} className="menu-content">
<ApiLogo info={spec.info} /> <ApiLogo info={spec.info} />
<SideMenuTitle>{store.spec.info.title}</SideMenuTitle>
{(!options.disableSearch && ( {(!options.disableSearch && (
<SearchBox <SearchBox
search={search!} search={search!}
@ -61,6 +73,7 @@ export class Redoc extends React.Component<RedocProps> {
</ApiContentWrap> </ApiContentWrap>
<BackgroundStub /> <BackgroundStub />
</RedocWrap> </RedocWrap>
<UnifiedFooter hideLocale={true} />
</OptionsProvider> </OptionsProvider>
</StoreProvider> </StoreProvider>
</ThemeProvider> </ThemeProvider>

View File

@ -1,5 +1,18 @@
import styled, { media } from '../../styled-components'; import styled, { media } from '../../styled-components';
export const StyledHeader = styled.header`
position: relative;
width: 100%;
z-index: 99;
`;
export const SideMenuTitle = styled.div`
font-size: 13px;
font-weight: bold;
line-height: 20px;
margin: 24px 16px;
`;
export const RedocWrap = styled.div` export const RedocWrap = styled.div`
${({ theme }) => ` ${({ theme }) => `
font-family: ${theme.typography.fontFamily}; font-family: ${theme.typography.fontFamily};

View File

@ -141,7 +141,7 @@ export class SearchBox extends React.PureComponent<SearchBoxProps, SearchBoxStat
.sort((a, b) => b.score - a.score); .sort((a, b) => b.score - a.score);
return ( return (
<SearchWrap role="search"> <SearchWrap role="search" data-role="redoc-search">
{this.state.term && <ClearIcon onClick={this.clear}>×</ClearIcon>} {this.state.term && <ClearIcon onClick={this.clear}>×</ClearIcon>}
<SearchIcon /> <SearchIcon />
<SearchInput <SearchInput

View File

@ -1,8 +1,10 @@
import { palette } from '@leafygreen-ui/palette';
import { default as classnames } from 'classnames'; import { default as classnames } from 'classnames';
import { darken } from 'polished'; import { darken } from 'polished';
import { deprecatedCss, ShelfIcon } from '../../common-elements'; import { deprecatedCss, ShelfIcon } from '../../common-elements';
import styled, { css, media, ResolvedThemeInterface } from '../../styled-components'; import styled, { css, media, ResolvedThemeInterface } from '../../styled-components';
import { getBadgeStyles } from '../../utils/styling';
export const OperationBadge = styled.span.attrs((props: { type: string }) => ({ export const OperationBadge = styled.span.attrs((props: { type: string }) => ({
className: `operation-type ${props.type}`, className: `operation-type ${props.type}`,
@ -12,11 +14,12 @@ export const OperationBadge = styled.span.attrs((props: { type: string }) => ({
height: ${props => props.theme.typography.code.fontSize}; height: ${props => props.theme.typography.code.fontSize};
line-height: ${props => props.theme.typography.code.fontSize}; line-height: ${props => props.theme.typography.code.fontSize};
background-color: #333; background-color: #333;
border-radius: 3px; border: ${props => props.theme.badges.border};
border-radius: ${props => props.theme.badges.borderRadius};
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: 6px 4px; background-position: 6px 4px;
font-size: 7px; font-size: 7px;
font-family: Verdana, sans-serif; // web-safe font-family: ${props => props.theme.typography.fontFamily};
color: white; color: white;
text-transform: uppercase; text-transform: uppercase;
text-align: center; text-align: center;
@ -25,45 +28,7 @@ export const OperationBadge = styled.span.attrs((props: { type: string }) => ({
margin-right: 6px; margin-right: 6px;
margin-top: 2px; margin-top: 2px;
&.get { ${props => getBadgeStyles(props.theme.colors.http[props.type], 'light')}
background-color: ${props => props.theme.colors.http.get};
}
&.post {
background-color: ${props => props.theme.colors.http.post};
}
&.put {
background-color: ${props => props.theme.colors.http.put};
}
&.options {
background-color: ${props => props.theme.colors.http.options};
}
&.patch {
background-color: ${props => props.theme.colors.http.patch};
}
&.delete {
background-color: ${props => props.theme.colors.http.delete};
}
&.basic {
background-color: ${props => props.theme.colors.http.basic};
}
&.link {
background-color: ${props => props.theme.colors.http.link};
}
&.head {
background-color: ${props => props.theme.colors.http.head};
}
&.hook {
background-color: ${props => props.theme.colors.primary.main};
}
`; `;
function menuItemActive( function menuItemActive(
@ -84,10 +49,6 @@ export const MenuItemUl = styled.ul<{ expanded: boolean }>`
margin: 0; margin: 0;
padding: 0; padding: 0;
&:first-child {
padding-bottom: 32px;
}
& & { & & {
font-size: 0.929em; font-size: 0.929em;
} }
@ -107,12 +68,12 @@ export const menuItemDepth = {
0: css` 0: css`
opacity: 0.7; opacity: 0.7;
text-transform: ${({ theme }) => theme.sidebar.groupItems.textTransform}; text-transform: ${({ theme }) => theme.sidebar.groupItems.textTransform};
font-size: 0.8em; font-size: 13px;
padding-bottom: 0; padding-bottom: 0;
cursor: default; cursor: default;
`, `,
1: css` 1: css`
font-size: 0.929em; font-size: 13px;
text-transform: ${({ theme }) => theme.sidebar.level1Items.textTransform}; text-transform: ${({ theme }) => theme.sidebar.level1Items.textTransform};
`, `,
}; };
@ -152,7 +113,7 @@ export const MenuItemLabel = styled.label.attrs((props: MenuItemLabelType) => ({
&:hover { &:hover {
color: ${props => menuItemActive(props.depth, props, 'activeTextColor')}; color: ${props => menuItemActive(props.depth, props, 'activeTextColor')};
background-color: ${props => menuItemActive(props.depth, props, 'activeBackgroundColor')}; background-color: ${palette.gray.light2};
} }
${ShelfIcon} { ${ShelfIcon} {
@ -170,6 +131,7 @@ export const MenuItemTitle = styled.span<{ width?: string }>`
width: ${props => (props.width ? props.width : 'auto')}; width: ${props => (props.width ? props.width : 'auto')};
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
font-size: 13px;
`; `;
export const RedocAttribution = styled.div` export const RedocAttribution = styled.div`
@ -177,7 +139,7 @@ export const RedocAttribution = styled.div`
font-size: 0.8em; font-size: 0.8em;
margin-top: ${theme.spacing.unit * 2}px; margin-top: ${theme.spacing.unit * 2}px;
text-align: center; text-align: center;
position: fixed; position: sticky;
width: ${theme.sidebar.width}; width: ${theme.sidebar.width};
bottom: 0; bottom: 0;
background: ${theme.sidebar.backgroundColor}; background: ${theme.sidebar.backgroundColor};

View File

@ -3,7 +3,7 @@
exports[`Components SchemaView OneOf deprecated should match snapshot 1`] = ` exports[`Components SchemaView OneOf deprecated should match snapshot 1`] = `
<div> <div>
<span <span
class="sc-kfYoZR juYXUf" class="sc-kfYoZR bZQYOp"
> >
One of One of
</span> </span>
@ -11,19 +11,19 @@ exports[`Components SchemaView OneOf deprecated should match snapshot 1`] = `
class="sc-dlMDgC EoFth" class="sc-dlMDgC EoFth"
> >
<button <button
class="sc-fKgJPI iEPbLk" class="sc-fKgJPI dAbXXY"
> >
string string
</button> </button>
<button <button
class="sc-fKgJPI bpjiHN" class="sc-fKgJPI jPXUyG"
> >
integer integer
</button> </button>
</div> </div>
<div> <div>
<span <span
class="sc-bqGGPW eSYQnm" class="sc-bqGGPW jPkJXo"
type="warning" type="warning"
> >
Deprecated Deprecated
@ -33,10 +33,10 @@ exports[`Components SchemaView OneOf deprecated should match snapshot 1`] = `
<div> <div>
<div> <div>
<span <span
class="sc-laZMeE sc-iNiQyp jWaWWE jrLlAa" class="sc-laZMeE sc-iNiQyp jWaWWE cctWcB"
/> />
<span <span
class="sc-laZMeE sc-jffHpj jWaWWE cThoNa" class="sc-laZMeE sc-jffHpj jWaWWE VHehP"
> >
string string
</span> </span>
@ -44,7 +44,7 @@ exports[`Components SchemaView OneOf deprecated should match snapshot 1`] = `
<div> <div>
<div <div
class="sc-iJCRrE sc-ciSkZP jCdxGr lhENGb" class="sc-iJCRrE sc-ciSkZP dTVIxT bVsrgw"
/> />
</div> </div>
</div> </div>

View File

@ -1,23 +1,23 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`SecurityRequirement should render SecurityDefs 1`] = ` exports[`SecurityRequirement should render SecurityDefs 1`] = `
"<div id=\\"section/Authentication/petstore_auth\\" data-section-id=\\"section/Authentication/petstore_auth\\" class=\\"sc-eCApnc jlMQbh\\"><div class=\\"sc-iCoGMd gLxhOh\\"><div class=\\"sc-hKFxyN juinod\\"><h2 class=\\"sc-pNWdM eftmgB\\">petstore_auth</h2><div class=\\"sc-iJCRrE sc-ciSkZP jCdxGr QGruV\\"><p>Get access to data while protecting your account credentials. "<div id=\\"section/Authentication/petstore_auth\\" data-section-id=\\"section/Authentication/petstore_auth\\" class=\\"sc-eCApnc gxBYnR\\"><div class=\\"sc-iCoGMd dglGZe\\"><div class=\\"sc-hKFxyN gXsFjB\\"><h2 class=\\"sc-pNWdM fyozOE\\">petstore_auth</h2><div class=\\"sc-iJCRrE sc-ciSkZP dTVIxT gmKdHC\\"><p>Get access to data while protecting your account credentials.
OAuth2 is also a safer and more secure way to give you access.</p> OAuth2 is also a safer and more secure way to give you access.</p>
</div><div class=\\"sc-EZqKI aOkZE\\"><div class=\\"sc-fXgAZx gZCyoW\\"><b>Security Scheme Type: </b><span>OAuth2</span></div><div class=\\"sc-iJCRrE sc-ciSkZP jCdxGr QGruV\\"><div class=\\"sc-fXgAZx gZCyoW\\"><b>Flow type: </b><code>implicit </code></div><div class=\\"sc-fXgAZx gZCyoW\\"><strong> Authorization URL: </strong><code><a target=\\"_blank\\" rel=\\"noopener noreferrer\\" href=\\"http://petstore.swagger.io/api/oauth/dialog\\">http://petstore.swagger.io/api/oauth/dialog</a></code></div><div class=\\"sc-fXgAZx gZCyoW\\"><b> Scopes: </b></div><div class=\\"sc-jXcxbT blWOKY container\\" style=\\"height: 4em;\\"><ul><li><code>write:pets</code> - <span class=\\"sc-carFqZ bmTzxo redoc-markdown\\"><p>modify pets in your account</p> </div><div class=\\"sc-EZqKI XgSsW\\"><div class=\\"sc-fXgAZx gZCyoW\\"><b>Security Scheme Type: </b><span>OAuth2</span></div><div class=\\"sc-iJCRrE sc-ciSkZP dTVIxT gmKdHC\\"><div class=\\"sc-fXgAZx gZCyoW\\"><b>Flow type: </b><code>implicit </code></div><div class=\\"sc-fXgAZx gZCyoW\\"><strong> Authorization URL: </strong><code><a target=\\"_blank\\" rel=\\"noopener noreferrer\\" href=\\"http://petstore.swagger.io/api/oauth/dialog\\">http://petstore.swagger.io/api/oauth/dialog</a></code></div><div class=\\"sc-fXgAZx gZCyoW\\"><b> Scopes: </b></div><div class=\\"sc-jXcxbT blWOKY container\\" style=\\"height: 4em;\\"><ul><li><code>write:pets</code> - <span class=\\"sc-carFqZ lasomv redoc-markdown\\"><p>modify pets in your account</p>
</span></li><li><code>read:pets</code> - <span class=\\"sc-carFqZ bmTzxo redoc-markdown\\"><p>read your pets</p> </span></li><li><code>read:pets</code> - <span class=\\"sc-carFqZ lasomv redoc-markdown\\"><p>read your pets</p>
</span></li></ul></div><div class=\\"sc-eEVmNe gbLbHj\\"></div></div></div></div></div></div><div id=\\"section/Authentication/GitLab_PersonalAccessToken\\" data-section-id=\\"section/Authentication/GitLab_PersonalAccessToken\\" class=\\"sc-eCApnc jlMQbh\\"><div class=\\"sc-iCoGMd gLxhOh\\"><div class=\\"sc-hKFxyN juinod\\"><h2 class=\\"sc-pNWdM eftmgB\\">GitLab_PersonalAccessToken</h2><div class=\\"sc-iJCRrE sc-ciSkZP jCdxGr QGruV\\"><p>GitLab Personal Access Token description</p> </span></li></ul></div><div class=\\"sc-eEVmNe gbLbHj\\"></div></div></div></div></div></div><div id=\\"section/Authentication/GitLab_PersonalAccessToken\\" data-section-id=\\"section/Authentication/GitLab_PersonalAccessToken\\" class=\\"sc-eCApnc gxBYnR\\"><div class=\\"sc-iCoGMd dglGZe\\"><div class=\\"sc-hKFxyN gXsFjB\\"><h2 class=\\"sc-pNWdM fyozOE\\">GitLab_PersonalAccessToken</h2><div class=\\"sc-iJCRrE sc-ciSkZP dTVIxT gmKdHC\\"><p>GitLab Personal Access Token description</p>
</div><div class=\\"sc-EZqKI aOkZE\\"><div class=\\"sc-fXgAZx gZCyoW\\"><b>Security Scheme Type: </b><span>API Key</span></div><div class=\\"sc-iJCRrE sc-ciSkZP jCdxGr QGruV\\"><div class=\\"sc-fXgAZx gZCyoW\\"><b>Header parameter name: </b><code>PRIVATE-TOKEN</code></div></div></div></div></div></div><div id=\\"section/Authentication/GitLab_OpenIdConnect\\" data-section-id=\\"section/Authentication/GitLab_OpenIdConnect\\" class=\\"sc-eCApnc jlMQbh\\"><div class=\\"sc-iCoGMd gLxhOh\\"><div class=\\"sc-hKFxyN juinod\\"><h2 class=\\"sc-pNWdM eftmgB\\">GitLab_OpenIdConnect</h2><div class=\\"sc-iJCRrE sc-ciSkZP jCdxGr QGruV\\"><p>GitLab OpenIdConnect description</p> </div><div class=\\"sc-EZqKI XgSsW\\"><div class=\\"sc-fXgAZx gZCyoW\\"><b>Security Scheme Type: </b><span>API Key</span></div><div class=\\"sc-iJCRrE sc-ciSkZP dTVIxT gmKdHC\\"><div class=\\"sc-fXgAZx gZCyoW\\"><b>Header parameter name: </b><code>PRIVATE-TOKEN</code></div></div></div></div></div></div><div id=\\"section/Authentication/GitLab_OpenIdConnect\\" data-section-id=\\"section/Authentication/GitLab_OpenIdConnect\\" class=\\"sc-eCApnc gxBYnR\\"><div class=\\"sc-iCoGMd dglGZe\\"><div class=\\"sc-hKFxyN gXsFjB\\"><h2 class=\\"sc-pNWdM fyozOE\\">GitLab_OpenIdConnect</h2><div class=\\"sc-iJCRrE sc-ciSkZP dTVIxT gmKdHC\\"><p>GitLab OpenIdConnect description</p>
</div><div class=\\"sc-EZqKI aOkZE\\"><div class=\\"sc-fXgAZx gZCyoW\\"><b>Security Scheme Type: </b><span>OpenID Connect</span></div><div class=\\"sc-iJCRrE sc-ciSkZP jCdxGr QGruV\\"><div class=\\"sc-fXgAZx gZCyoW\\"><b>Connect URL: </b><code><a target=\\"_blank\\" rel=\\"noopener noreferrer\\" href=\\"https://gitlab.com/.well-known/openid-configuration\\">https://gitlab.com/.well-known/openid-configuration</a></code></div></div></div></div></div></div><div id=\\"section/Authentication/basicAuth\\" data-section-id=\\"section/Authentication/basicAuth\\" class=\\"sc-eCApnc jlMQbh\\"><div class=\\"sc-iCoGMd gLxhOh\\"><div class=\\"sc-hKFxyN juinod\\"><h2 class=\\"sc-pNWdM eftmgB\\">basicAuth</h2><div class=\\"sc-iJCRrE sc-ciSkZP jCdxGr QGruV\\"></div><div class=\\"sc-EZqKI aOkZE\\"><div class=\\"sc-fXgAZx gZCyoW\\"><b>Security Scheme Type: </b><span>HTTP</span></div><div class=\\"sc-iJCRrE sc-ciSkZP jCdxGr QGruV\\"><div class=\\"sc-fXgAZx gZCyoW\\"><b>HTTP Authorization Scheme: </b><code>basic</code></div><div class=\\"sc-fXgAZx gZCyoW\\"></div></div></div></div></div></div>" </div><div class=\\"sc-EZqKI XgSsW\\"><div class=\\"sc-fXgAZx gZCyoW\\"><b>Security Scheme Type: </b><span>OpenID Connect</span></div><div class=\\"sc-iJCRrE sc-ciSkZP dTVIxT gmKdHC\\"><div class=\\"sc-fXgAZx gZCyoW\\"><b>Connect URL: </b><code><a target=\\"_blank\\" rel=\\"noopener noreferrer\\" href=\\"https://gitlab.com/.well-known/openid-configuration\\">https://gitlab.com/.well-known/openid-configuration</a></code></div></div></div></div></div></div><div id=\\"section/Authentication/basicAuth\\" data-section-id=\\"section/Authentication/basicAuth\\" class=\\"sc-eCApnc gxBYnR\\"><div class=\\"sc-iCoGMd dglGZe\\"><div class=\\"sc-hKFxyN gXsFjB\\"><h2 class=\\"sc-pNWdM fyozOE\\">basicAuth</h2><div class=\\"sc-iJCRrE sc-ciSkZP dTVIxT gmKdHC\\"></div><div class=\\"sc-EZqKI XgSsW\\"><div class=\\"sc-fXgAZx gZCyoW\\"><b>Security Scheme Type: </b><span>HTTP</span></div><div class=\\"sc-iJCRrE sc-ciSkZP dTVIxT gmKdHC\\"><div class=\\"sc-fXgAZx gZCyoW\\"><b>HTTP Authorization Scheme: </b><code>basic</code></div><div class=\\"sc-fXgAZx gZCyoW\\"></div></div></div></div></div></div>"
`; `;
exports[`SecurityRequirement should render authDefinition 1`] = `"<div class=\\"sc-bQCEYZ eDdCgW\\"><div class=\\"sc-xGAEC femyTb\\"><h5 class=\\"sc-iqAclL sc-jHcXXw eONCmm keQLTh\\">Authorizations:</h5><svg class=\\"sc-dIsUp iPqByX\\" version=\\"1.1\\" viewBox=\\"0 0 24 24\\" x=\\"0\\" xmlns=\\"http://www.w3.org/2000/svg\\" y=\\"0\\" aria-hidden=\\"true\\"><polygon points=\\"17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 \\"></polygon></svg></div><div class=\\"sc-dWBRfb kJFNCL\\"><span class=\\"sc-kYPZxB irJeRy\\">(<span class=\\"sc-hzUIXc gcouO\\">API Key: <i>GitLab_PersonalAccessToken</i></span><span class=\\"sc-hzUIXc gcouO\\">OpenID Connect: <i>GitLab_OpenIdConnect</i></span><span class=\\"sc-hzUIXc gcouO\\">HTTP: <i>basicAuth</i></span>) </span><span class=\\"sc-kYPZxB irJeRy\\"><span class=\\"sc-hzUIXc gcouO\\">OAuth2: <i>petstore_auth</i></span></span></div></div>,"`; exports[`SecurityRequirement should render authDefinition 1`] = `"<div class=\\"sc-bQCEYZ dFCVnY\\"><div class=\\"sc-xGAEC femyTb\\"><h5 class=\\"sc-iqAclL sc-jHcXXw eONCmm keQLTh\\">Authorizations:</h5><svg class=\\"sc-dIsUp iPqByX\\" version=\\"1.1\\" viewBox=\\"0 0 24 24\\" x=\\"0\\" xmlns=\\"http://www.w3.org/2000/svg\\" y=\\"0\\" aria-hidden=\\"true\\"><polygon points=\\"17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 \\"></polygon></svg></div><div class=\\"sc-dWBRfb egUPBF\\"><span class=\\"sc-kYPZxB hfhKoI\\">(<span class=\\"sc-hzUIXc jFcJRk\\">API Key: <i>GitLab_PersonalAccessToken</i></span><span class=\\"sc-hzUIXc jFcJRk\\">OpenID Connect: <i>GitLab_OpenIdConnect</i></span><span class=\\"sc-hzUIXc jFcJRk\\">HTTP: <i>basicAuth</i></span>) </span><span class=\\"sc-kYPZxB hfhKoI\\"><span class=\\"sc-hzUIXc jFcJRk\\">OAuth2: <i>petstore_auth</i></span></span></div></div>,"`;
exports[`SecurityRequirement should render authDefinition 2`] = ` exports[`SecurityRequirement should render authDefinition 2`] = `
"<div class=\\"sc-bQCEYZ dSwEDq\\"><div class=\\"sc-xGAEC femyTb\\"><h5 class=\\"sc-iqAclL sc-jHcXXw eONCmm keQLTh\\">Authorizations:</h5><svg class=\\"sc-dIsUp fVWtGJ\\" version=\\"1.1\\" viewBox=\\"0 0 24 24\\" x=\\"0\\" xmlns=\\"http://www.w3.org/2000/svg\\" y=\\"0\\" aria-hidden=\\"true\\"><polygon points=\\"17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 \\"></polygon></svg></div><div class=\\"sc-dWBRfb ekRdav\\"><span class=\\"sc-kYPZxB fhGdrc\\">(<span class=\\"sc-hzUIXc gcouO\\">API Key: <i>GitLab_PersonalAccessToken</i></span><span class=\\"sc-hzUIXc gcouO\\">OpenID Connect: <i>GitLab_OpenIdConnect</i></span><span class=\\"sc-hzUIXc gcouO\\">HTTP: <i>basicAuth</i></span>) </span><span class=\\"sc-kYPZxB fhGdrc\\"><span class=\\"sc-hzUIXc gcouO\\">OAuth2: <i>petstore_auth</i> (<code class=\\"sc-eHEENL fwFTyL\\">write:pets</code><code class=\\"sc-eHEENL fwFTyL\\">read:pets</code>) </span></span></div></div><div class=\\"sc-EZqKI aOkZE\\"><h5><svg xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"0 0 24 24\\" width=\\"11\\" height=\\"11\\"><path fill=\\"currentColor\\" d=\\"M18 10V6A6 6 0 0 0 6 6v4H3v14h18V10h-3zM8 6c0-2.206 1.794-4 4-4s4 1.794 4 4v4H8V6zm11 16H5V12h14v10z\\"></path></svg> OAuth2: petstore_auth</h5><div class=\\"sc-iJCRrE sc-ciSkZP jCdxGr QGruV\\"><p>Get access to data while protecting your account credentials. "<div class=\\"sc-bQCEYZ cHLZiQ\\"><div class=\\"sc-xGAEC femyTb\\"><h5 class=\\"sc-iqAclL sc-jHcXXw eONCmm keQLTh\\">Authorizations:</h5><svg class=\\"sc-dIsUp fVWtGJ\\" version=\\"1.1\\" viewBox=\\"0 0 24 24\\" x=\\"0\\" xmlns=\\"http://www.w3.org/2000/svg\\" y=\\"0\\" aria-hidden=\\"true\\"><polygon points=\\"17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 \\"></polygon></svg></div><div class=\\"sc-dWBRfb iXBOyl\\"><span class=\\"sc-kYPZxB fUZJUa\\">(<span class=\\"sc-hzUIXc jFcJRk\\">API Key: <i>GitLab_PersonalAccessToken</i></span><span class=\\"sc-hzUIXc jFcJRk\\">OpenID Connect: <i>GitLab_OpenIdConnect</i></span><span class=\\"sc-hzUIXc jFcJRk\\">HTTP: <i>basicAuth</i></span>) </span><span class=\\"sc-kYPZxB fUZJUa\\"><span class=\\"sc-hzUIXc jFcJRk\\">OAuth2: <i>petstore_auth</i> (<code class=\\"sc-eHEENL ktuYhQ\\">write:pets</code><code class=\\"sc-eHEENL ktuYhQ\\">read:pets</code>) </span></span></div></div><div class=\\"sc-EZqKI XgSsW\\"><h5><svg xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"0 0 24 24\\" width=\\"11\\" height=\\"11\\"><path fill=\\"currentColor\\" d=\\"M18 10V6A6 6 0 0 0 6 6v4H3v14h18V10h-3zM8 6c0-2.206 1.794-4 4-4s4 1.794 4 4v4H8V6zm11 16H5V12h14v10z\\"></path></svg> OAuth2: petstore_auth</h5><div class=\\"sc-iJCRrE sc-ciSkZP dTVIxT gmKdHC\\"><p>Get access to data while protecting your account credentials.
OAuth2 is also a safer and more secure way to give you access.</p> OAuth2 is also a safer and more secure way to give you access.</p>
</div><div class=\\"sc-iJCRrE sc-ciSkZP jCdxGr QGruV\\"><div class=\\"sc-fXgAZx gZCyoW\\"><b>Flow type: </b><code>implicit </code></div><div class=\\"sc-fXgAZx gZCyoW\\"><strong> Authorization URL: </strong><code><a target=\\"_blank\\" rel=\\"noopener noreferrer\\" href=\\"http://petstore.swagger.io/api/oauth/dialog\\">http://petstore.swagger.io/api/oauth/dialog</a></code></div><div><b>Required scopes: </b><code>write:pets</code> <code>read:pets</code> </div><div class=\\"sc-fXgAZx gZCyoW\\"><b> Scopes: </b></div><div class=\\"sc-jXcxbT blWOKY container\\" style=\\"height: 4em;\\"><ul><li><code>write:pets</code> - <span class=\\"sc-carFqZ bmTzxo redoc-markdown\\"><p>modify pets in your account</p> </div><div class=\\"sc-iJCRrE sc-ciSkZP dTVIxT gmKdHC\\"><div class=\\"sc-fXgAZx gZCyoW\\"><b>Flow type: </b><code>implicit </code></div><div class=\\"sc-fXgAZx gZCyoW\\"><strong> Authorization URL: </strong><code><a target=\\"_blank\\" rel=\\"noopener noreferrer\\" href=\\"http://petstore.swagger.io/api/oauth/dialog\\">http://petstore.swagger.io/api/oauth/dialog</a></code></div><div><b>Required scopes: </b><code>write:pets</code> <code>read:pets</code> </div><div class=\\"sc-fXgAZx gZCyoW\\"><b> Scopes: </b></div><div class=\\"sc-jXcxbT blWOKY container\\" style=\\"height: 4em;\\"><ul><li><code>write:pets</code> - <span class=\\"sc-carFqZ lasomv redoc-markdown\\"><p>modify pets in your account</p>
</span></li><li><code>read:pets</code> - <span class=\\"sc-carFqZ bmTzxo redoc-markdown\\"><p>read your pets</p> </span></li><li><code>read:pets</code> - <span class=\\"sc-carFqZ lasomv redoc-markdown\\"><p>read your pets</p>
</span></li></ul></div><div class=\\"sc-eEVmNe gbLbHj\\"></div></div></div><div class=\\"sc-EZqKI aOkZE\\"><h5><svg xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"0 0 24 24\\" width=\\"11\\" height=\\"11\\"><path fill=\\"currentColor\\" d=\\"M18 10V6A6 6 0 0 0 6 6v4H3v14h18V10h-3zM8 6c0-2.206 1.794-4 4-4s4 1.794 4 4v4H8V6zm11 16H5V12h14v10z\\"></path></svg> API Key: GitLab_PersonalAccessToken</h5><div class=\\"sc-iJCRrE sc-ciSkZP jCdxGr QGruV\\"><p>GitLab Personal Access Token description</p> </span></li></ul></div><div class=\\"sc-eEVmNe gbLbHj\\"></div></div></div><div class=\\"sc-EZqKI XgSsW\\"><h5><svg xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"0 0 24 24\\" width=\\"11\\" height=\\"11\\"><path fill=\\"currentColor\\" d=\\"M18 10V6A6 6 0 0 0 6 6v4H3v14h18V10h-3zM8 6c0-2.206 1.794-4 4-4s4 1.794 4 4v4H8V6zm11 16H5V12h14v10z\\"></path></svg> API Key: GitLab_PersonalAccessToken</h5><div class=\\"sc-iJCRrE sc-ciSkZP dTVIxT gmKdHC\\"><p>GitLab Personal Access Token description</p>
</div><div class=\\"sc-iJCRrE sc-ciSkZP jCdxGr QGruV\\"><div class=\\"sc-fXgAZx gZCyoW\\"><b>Header parameter name: </b><code>PRIVATE-TOKEN</code></div></div></div><div class=\\"sc-EZqKI aOkZE\\"><h5><svg xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"0 0 24 24\\" width=\\"11\\" height=\\"11\\"><path fill=\\"currentColor\\" d=\\"M18 10V6A6 6 0 0 0 6 6v4H3v14h18V10h-3zM8 6c0-2.206 1.794-4 4-4s4 1.794 4 4v4H8V6zm11 16H5V12h14v10z\\"></path></svg> OpenID Connect: GitLab_OpenIdConnect</h5><div class=\\"sc-iJCRrE sc-ciSkZP jCdxGr QGruV\\"><p>GitLab OpenIdConnect description</p> </div><div class=\\"sc-iJCRrE sc-ciSkZP dTVIxT gmKdHC\\"><div class=\\"sc-fXgAZx gZCyoW\\"><b>Header parameter name: </b><code>PRIVATE-TOKEN</code></div></div></div><div class=\\"sc-EZqKI XgSsW\\"><h5><svg xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"0 0 24 24\\" width=\\"11\\" height=\\"11\\"><path fill=\\"currentColor\\" d=\\"M18 10V6A6 6 0 0 0 6 6v4H3v14h18V10h-3zM8 6c0-2.206 1.794-4 4-4s4 1.794 4 4v4H8V6zm11 16H5V12h14v10z\\"></path></svg> OpenID Connect: GitLab_OpenIdConnect</h5><div class=\\"sc-iJCRrE sc-ciSkZP dTVIxT gmKdHC\\"><p>GitLab OpenIdConnect description</p>
</div><div class=\\"sc-iJCRrE sc-ciSkZP jCdxGr QGruV\\"><div class=\\"sc-fXgAZx gZCyoW\\"><b>Connect URL: </b><code><a target=\\"_blank\\" rel=\\"noopener noreferrer\\" href=\\"https://gitlab.com/.well-known/openid-configuration\\">https://gitlab.com/.well-known/openid-configuration</a></code></div></div></div><div class=\\"sc-EZqKI aOkZE\\"><h5><svg xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"0 0 24 24\\" width=\\"11\\" height=\\"11\\"><path fill=\\"currentColor\\" d=\\"M18 10V6A6 6 0 0 0 6 6v4H3v14h18V10h-3zM8 6c0-2.206 1.794-4 4-4s4 1.794 4 4v4H8V6zm11 16H5V12h14v10z\\"></path></svg> HTTP: basicAuth</h5><div class=\\"sc-iJCRrE sc-ciSkZP jCdxGr QGruV\\"></div><div class=\\"sc-iJCRrE sc-ciSkZP jCdxGr QGruV\\"><div class=\\"sc-fXgAZx gZCyoW\\"><b>HTTP Authorization Scheme: </b><code>basic</code></div><div class=\\"sc-fXgAZx gZCyoW\\"></div></div></div>," </div><div class=\\"sc-iJCRrE sc-ciSkZP dTVIxT gmKdHC\\"><div class=\\"sc-fXgAZx gZCyoW\\"><b>Connect URL: </b><code><a target=\\"_blank\\" rel=\\"noopener noreferrer\\" href=\\"https://gitlab.com/.well-known/openid-configuration\\">https://gitlab.com/.well-known/openid-configuration</a></code></div></div></div><div class=\\"sc-EZqKI XgSsW\\"><h5><svg xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"0 0 24 24\\" width=\\"11\\" height=\\"11\\"><path fill=\\"currentColor\\" d=\\"M18 10V6A6 6 0 0 0 6 6v4H3v14h18V10h-3zM8 6c0-2.206 1.794-4 4-4s4 1.794 4 4v4H8V6zm11 16H5V12h14v10z\\"></path></svg> HTTP: basicAuth</h5><div class=\\"sc-iJCRrE sc-ciSkZP dTVIxT gmKdHC\\"></div><div class=\\"sc-iJCRrE sc-ciSkZP dTVIxT gmKdHC\\"><div class=\\"sc-fXgAZx gZCyoW\\"><b>HTTP Authorization Scheme: </b><code>basic</code></div><div class=\\"sc-fXgAZx gZCyoW\\"></div></div></div>,"
`; `;

View File

@ -1,20 +1,25 @@
import { darken, desaturate, lighten, readableColor, transparentize } from 'polished'; import { darken, lighten, readableColor, transparentize } from 'polished';
import { palette } from '@leafygreen-ui/palette';
const textFontFamily =
'"Euclid Circular A", Akzidenz, "Helvetica Neue", Helvetica, Arial, sans-serif';
const codeFontFamily = 'Source Code Pro';
const defaultTheme: ThemeInterface = { const defaultTheme: ThemeInterface = {
spacing: { spacing: {
unit: 5, unit: 4,
sectionHorizontal: ({ spacing }) => spacing.unit * 8, sectionHorizontal: ({ spacing }) => spacing.unit * 8,
sectionVertical: ({ spacing }) => spacing.unit * 8, sectionVertical: 16,
}, },
breakpoints: { breakpoints: {
small: '50rem', small: '768px',
medium: '75rem', medium: '1024px',
large: '105rem', large: '1200px',
}, },
colors: { colors: {
tonalOffset: 0.2, tonalOffset: 0.2,
primary: { primary: {
main: '#32329f', main: palette.black,
light: ({ colors }) => lighten(colors.tonalOffset, colors.primary.main), light: ({ colors }) => lighten(colors.tonalOffset, colors.primary.main),
dark: ({ colors }) => darken(colors.tonalOffset, colors.primary.main), dark: ({ colors }) => darken(colors.tonalOffset, colors.primary.main),
contrastText: ({ colors }) => readableColor(colors.primary.main), contrastText: ({ colors }) => readableColor(colors.primary.main),
@ -26,13 +31,13 @@ const defaultTheme: ThemeInterface = {
contrastText: ({ colors }) => readableColor(colors.success.main), contrastText: ({ colors }) => readableColor(colors.success.main),
}, },
warning: { warning: {
main: '#ffa500', main: palette.gray.light1,
light: ({ colors }) => lighten(colors.tonalOffset, colors.warning.main), light: ({ colors }) => lighten(colors.tonalOffset, colors.warning.main),
dark: ({ colors }) => darken(colors.tonalOffset, colors.warning.main), dark: ({ colors }) => darken(colors.tonalOffset, colors.warning.main),
contrastText: '#ffffff', contrastText: palette.gray.dark1,
}, },
error: { error: {
main: '#d41f1c', main: palette.red.base,
light: ({ colors }) => lighten(colors.tonalOffset, colors.error.main), light: ({ colors }) => lighten(colors.tonalOffset, colors.error.main),
dark: ({ colors }) => darken(colors.tonalOffset, colors.error.main), dark: ({ colors }) => darken(colors.tonalOffset, colors.error.main),
contrastText: ({ colors }) => readableColor(colors.error.main), contrastText: ({ colors }) => readableColor(colors.error.main),
@ -42,7 +47,7 @@ const defaultTheme: ThemeInterface = {
100: '#F5F5F5', 100: '#F5F5F5',
}, },
text: { text: {
primary: '#333333', primary: palette.gray.dark3,
secondary: ({ colors }) => lighten(colors.tonalOffset, colors.text.primary), secondary: ({ colors }) => lighten(colors.tonalOffset, colors.text.primary),
}, },
border: { border: {
@ -51,14 +56,14 @@ const defaultTheme: ThemeInterface = {
}, },
responses: { responses: {
success: { success: {
color: ({ colors }) => colors.success.main, color: palette.green.dark2,
backgroundColor: ({ colors }) => transparentize(0.93, colors.success.main), backgroundColor: palette.green.light3,
tabTextColor: ({ colors }) => colors.responses.success.color, tabTextColor: palette.green.base,
}, },
error: { error: {
color: ({ colors }) => colors.error.main, color: palette.red.base,
backgroundColor: ({ colors }) => transparentize(0.93, colors.error.main), backgroundColor: palette.red.light3,
tabTextColor: ({ colors }) => colors.responses.error.color, tabTextColor: palette.red.base,
}, },
redirect: { redirect: {
color: ({ colors }) => colors.warning.main, color: ({ colors }) => colors.warning.main,
@ -72,27 +77,78 @@ const defaultTheme: ThemeInterface = {
}, },
}, },
http: { http: {
get: '#2F8132', get: {
post: '#186FAF', light: {
put: '#95507c', backgroundColor: palette.blue.light3,
borderColor: palette.blue.light2,
color: palette.blue.dark1,
},
dark: {
backgroundColor: palette.blue.dark2,
borderColor: palette.blue.dark1,
color: palette.blue.light2,
},
},
post: {
light: {
backgroundColor: palette.green.light3,
borderColor: palette.green.light2,
color: palette.green.dark2,
},
dark: {
backgroundColor: palette.green.dark3,
borderColor: palette.green.dark2,
color: palette.green.base,
},
},
put: {
light: {
backgroundColor: palette.yellow.light3,
borderColor: palette.yellow.light2,
color: palette.yellow.dark2,
},
dark: {
backgroundColor: palette.yellow.dark3,
borderColor: palette.yellow.dark2,
color: palette.yellow.light2,
},
},
options: '#947014', options: '#947014',
patch: '#bf581d', patch: {
delete: '#cc3333', light: {
backgroundColor: palette.yellow.light3,
borderColor: palette.yellow.light2,
color: palette.yellow.dark2,
},
dark: {
backgroundColor: palette.yellow.dark3,
borderColor: palette.yellow.dark2,
color: palette.yellow.light2,
},
},
delete: {
light: {
backgroundColor: palette.red.light3,
borderColor: palette.red.light2,
color: palette.red.dark2,
},
dark: {
backgroundColor: palette.red.dark3,
borderColor: palette.red.dark2,
color: palette.red.light2,
},
},
basic: '#707070', basic: '#707070',
link: '#07818F', link: '#07818F',
head: '#A23DAD', head: '#A23DAD',
}, },
}, },
schema: { schema: {
linesColor: theme => linesColor: palette.black,
lighten(
theme.colors.tonalOffset,
desaturate(theme.colors.tonalOffset, theme.colors.primary.main),
),
defaultDetailsWidth: '75%', defaultDetailsWidth: '75%',
typeNameColor: theme => theme.colors.text.secondary, typeNameColor: palette.gray.dark3,
typeTitleColor: theme => theme.schema.typeNameColor, typeTitleColor: theme => theme.schema.typeNameColor,
requireLabelColor: theme => theme.colors.error.main, requireLabelColor: palette.red.base,
labelsTextSize: '0.9em', labelsTextSize: '0.9em',
nestingSpacing: '1em', nestingSpacing: '1em',
nestedBackground: '#fafafa', nestedBackground: '#fafafa',
@ -102,51 +158,48 @@ const defaultTheme: ThemeInterface = {
}, },
}, },
typography: { typography: {
fontSize: '14px', fontSize: '16px',
lineHeight: '1.5em', lineHeight: '1.5em',
fontWeightRegular: '400', fontWeightRegular: '400',
fontWeightBold: '600', fontWeightBold: '600',
fontWeightLight: '300', fontWeightLight: '300',
fontFamily: 'Roboto, sans-serif', fontFamily: textFontFamily,
smoothing: 'antialiased', smoothing: 'antialiased',
optimizeSpeed: true, optimizeSpeed: true,
headings: { headings: {
fontFamily: 'Montserrat, sans-serif', fontFamily: textFontFamily,
fontWeight: '400', fontWeight: '400',
lineHeight: '1.6em', lineHeight: '1.6em',
}, },
code: { code: {
fontSize: '13px', fontSize: '13px',
fontFamily: 'Courier, monospace', fontFamily: codeFontFamily,
lineHeight: ({ typography }) => typography.lineHeight, lineHeight: ({ typography }) => typography.lineHeight,
fontWeight: ({ typography }) => typography.fontWeightRegular, fontWeight: ({ typography }) => typography.fontWeightRegular,
color: '#e53935', color: palette.gray.dark3,
backgroundColor: 'rgba(38, 50, 56, 0.05)', backgroundColor: palette.gray.light3,
wrap: false, wrap: false,
}, },
links: { links: {
color: ({ colors }) => colors.primary.main, color: palette.blue.base,
visited: ({ typography }) => typography.links.color, visited: palette.blue.base,
hover: ({ typography }) => lighten(0.2, typography.links.color), hover: palette.blue.base,
textDecoration: 'auto', textDecoration: 'auto',
hoverTextDecoration: 'auto', hoverTextDecoration: 'auto',
}, },
}, },
sidebar: { sidebar: {
width: '260px', width: '268px',
backgroundColor: '#fafafa', backgroundColor: palette.gray.light3,
textColor: '#333333', textColor: palette.black,
activeTextColor: theme => activeTextColor: palette.green.dark3,
theme.sidebar.textColor !== defaultTheme.sidebar!.textColor
? theme.sidebar.textColor
: theme.colors.primary.main,
groupItems: { groupItems: {
activeBackgroundColor: theme => darken(0.1, theme.sidebar.backgroundColor), activeBackgroundColor: palette.green.light3,
activeTextColor: theme => theme.sidebar.activeTextColor, activeTextColor: theme => theme.sidebar.activeTextColor,
textTransform: 'uppercase', textTransform: 'uppercase',
}, },
level1Items: { level1Items: {
activeBackgroundColor: theme => darken(0.05, theme.sidebar.backgroundColor), activeBackgroundColor: palette.green.light3,
activeTextColor: theme => theme.sidebar.activeTextColor, activeTextColor: theme => theme.sidebar.activeTextColor,
textTransform: 'none', textTransform: 'none',
}, },
@ -161,26 +214,30 @@ const defaultTheme: ThemeInterface = {
gutter: '2px', gutter: '2px',
}, },
rightPanel: { rightPanel: {
backgroundColor: '#263238', backgroundColor: palette.black,
width: '40%', width: '40%',
textColor: '#ffffff', textColor: '#ffffff',
servers: { servers: {
overlay: { overlay: {
backgroundColor: '#fafafa', backgroundColor: palette.gray.dark3,
textColor: '#263238', textColor: palette.white,
}, },
url: { url: {
backgroundColor: '#fff', backgroundColor: palette.gray.dark3,
}, },
}, },
}, },
codeBlock: { codeBlock: {
backgroundColor: ({ rightPanel }) => darken(0.1, rightPanel.backgroundColor), backgroundColor: palette.gray.dark3,
}, },
fab: { fab: {
backgroundColor: '#f2f2f2', backgroundColor: '#f2f2f2',
color: '#0065FB', color: '#0065FB',
}, },
badges: {
border: '1px solid',
borderRadius: '5px',
},
}; };
export default defaultTheme; export default defaultTheme;
@ -232,6 +289,17 @@ export interface HTTPResponseColos {
tabTextColor: string; tabTextColor: string;
} }
export interface HTTPBadgeOptions {
backgroundColor: string;
borderColor: string;
color: string;
}
export interface HTTPBadgeColors {
light: HTTPBadgeOptions;
dark: HTTPBadgeOptions;
}
export interface FontSettings { export interface FontSettings {
fontSize: string; fontSize: string;
fontWeight: string; fontWeight: string;
@ -286,12 +354,12 @@ export interface ResolvedThemeInterface {
info: HTTPResponseColos; info: HTTPResponseColos;
}; };
http: { http: {
get: string; get: HTTPBadgeColors;
post: string; post: HTTPBadgeColors;
put: string; put: HTTPBadgeColors;
options: string; options: string;
patch: string; patch: HTTPBadgeColors;
delete: string; delete: HTTPBadgeColors;
basic: string; basic: string;
link: string; link: string;
head: string; head: string;
@ -378,6 +446,10 @@ export interface ResolvedThemeInterface {
backgroundColor: string; backgroundColor: string;
color: string; color: string;
}; };
badges: {
border: string;
borderRadius: string;
};
extensionsHook?: (name: string, props: any) => string; extensionsHook?: (name: string, props: any) => string;
} }

28
src/utils/styling.ts Normal file
View File

@ -0,0 +1,28 @@
import type { HTTPBadgeColors } from '../theme';
/**
* Uses theming options to return appropriate styling for badges. Some badges may not
* currently have custom styling.
*
* @param badgeColors
* @param colorTheme
* @returns string
*/
export function getBadgeStyles(badgeColors: HTTPBadgeColors | string, colorTheme: string): string {
const defaultBackgroundColor = '#999999';
// Guard for dev mode; some types temporarily appear as undefined
if (badgeColors === undefined) return `background-color: ${defaultBackgroundColor};`;
if (typeof badgeColors === 'string') {
return `
background-color: ${badgeColors || defaultBackgroundColor};
`;
} else {
return `
background-color: ${badgeColors[colorTheme].backgroundColor};
border-color: ${badgeColors[colorTheme].borderColor};
color: ${badgeColors[colorTheme].color};
`;
}
}