This commit is contained in:
galela 2025-05-21 23:47:49 +08:00 committed by GitHub
commit 110f225764
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
28 changed files with 168 additions and 114 deletions

View File

@ -9,10 +9,10 @@ export const PropertiesTableCaption = styled.caption`
`; `;
export const PropertyCell = styled.td<{ kind?: string }>` export const PropertyCell = styled.td<{ kind?: string }>`
border-left: 1px solid ${props => props.theme.schema.linesColor}; border-left: 1px dashed ${props => props.theme.schema.linesColor};
box-sizing: border-box; box-sizing: border-box;
position: relative; position: relative;
padding: 10px 10px 10px 0; padding: 10px;
${media.lessThan('small')` ${media.lessThan('small')`
display: block; display: block;
@ -28,23 +28,28 @@ export const PropertyCell = styled.td<{ kind?: string }>`
} }
tr:first-of-type > & { tr:first-of-type > & {
background-image: linear-gradient( background-image: repeating-linear-gradient(
to bottom, 0deg,
transparent 0%, ${props => props.theme.schema.linesColor},
transparent 22px, ${props => props.theme.schema.linesColor} 3px,
${props => props.theme.schema.linesColor} 22px, transparent 3px,
${props => props.theme.schema.linesColor} 100% transparent 5px,
${props => props.theme.schema.linesColor} 5px
); );
background-position: 0 10px;
padding-top: 0;
} }
tr.last > & { tr.last > & {
background-image: linear-gradient( background-image: repeating-linear-gradient(
to bottom, 0deg,
${props => props.theme.schema.linesColor} 0%, ${props => props.theme.schema.linesColor},
${props => props.theme.schema.linesColor} 22px, ${props => props.theme.schema.linesColor} 3px,
transparent 22px, transparent 3px,
transparent 100% transparent 5px,
${props => props.theme.schema.linesColor} 5px
); );
background-size: 1px 22px;
} }
tr.last + tr > & { tr.last + tr > & {
@ -97,7 +102,7 @@ export const PropertyNameCell = styled(PropertyCell)`
`; `;
export const PropertyDetailsCell = styled.td` export const PropertyDetailsCell = styled.td`
border-bottom: 1px solid #9fb4be; border-bottom: 1px solid rgb(228, 231, 235);
padding: 10px 0; padding: 10px 0;
width: ${props => props.theme.schema.defaultDetailsWidth}; width: ${props => props.theme.schema.defaultDetailsWidth};
box-sizing: border-box; box-sizing: border-box;
@ -109,12 +114,15 @@ export const PropertyDetailsCell = styled.td`
${media.lessThan('small')` ${media.lessThan('small')`
padding: 0 20px; padding: 0 20px;
border-bottom: none; border-bottom: none;
border-left: 1px solid ${props => props.theme.schema.linesColor}; border-left: 1px dashed ${props => props.theme.schema.linesColor};
tr.last > & { tr.last > & {
border-left: none; border-left: none;
} }
`} `}
tr:first-of-type > & {
padding-top: 0;
}
${extensionsHook('PropertyDetailsCell')}; ${extensionsHook('PropertyDetailsCell')};
`; `;
@ -163,6 +171,7 @@ export const PropertiesTable = styled.table`
display: block; display: block;
> tr, > tbody > tr { > tr, > tbody > tr {
display: block; display: block;
padding-bottom:10px;
} }
`} `}

View File

@ -56,7 +56,7 @@ export const ClickablePropertyNameCell = styled(PropertyNameCell)`
`; `;
export const FieldLabel = styled.span` export const FieldLabel = styled.span`
vertical-align: middle; vertical-align: top;
font-size: ${({ theme }) => theme.typography.code.fontSize}; font-size: ${({ theme }) => theme.typography.code.fontSize};
line-height: 20px; line-height: 20px;
`; `;
@ -82,7 +82,6 @@ export const RequiredLabel = styled(FieldLabel).attrs({
color: ${props => props.theme.schema.requireLabelColor}; color: ${props => props.theme.schema.requireLabelColor};
font-size: ${props => props.theme.schema.labelsTextSize}; font-size: ${props => props.theme.schema.labelsTextSize};
font-weight: normal; font-weight: normal;
margin-left: 20px;
line-height: 1; line-height: 1;
`; `;

View File

@ -35,20 +35,24 @@ export const H3 = styled.h2`
${extensionsHook('H3')}; ${extensionsHook('H3')};
`; `;
export const RightPanelHeader = styled.h3` export const RightPanelHeader = styled.div`
color: ${({ theme }) => theme.rightPanel.textColor}; color: #ffffff;
padding: 10px;
font-weight: 700;
border-radius: 4px 4px 0 0;
background: rgb(50, 63, 75);
${extensionsHook('RightPanelHeader')}; ${extensionsHook('RightPanelHeader')};
`; `;
export const UnderlinedHeader = styled.h5` export const UnderlinedHeader = styled.h5`
border-bottom: 1px solid rgba(38, 50, 56, 0.3);
margin: 1em 0 1em 0; margin: 1em 0 1em 0;
color: rgba(38, 50, 56, 0.5); color: rgb(96, 106, 119);
font-weight: normal; font-weight: bold;
text-transform: uppercase; text-transform: uppercase;
font-size: 0.929em; font-size: 0.929em;
line-height: 20px; line-height: 20px;
border-bottom: 1px solid rgb(228, 231, 235);
padding-bottom: 0.8em;
${extensionsHook('UnderlinedHeader')}; ${extensionsHook('UnderlinedHeader')};
`; `;

View File

@ -12,6 +12,12 @@ export const MiddlePanel = styled.div<{ $compact?: boolean }>`
theme.spacing.sectionHorizontal theme.spacing.sectionHorizontal
}px`}; }px`};
`}; `};
${({ $compact, theme }) =>
media.lessThan('small', true)`
padding: ${`${$compact ? 0 : theme.spacing.sectionVertical / 2}px ${
theme.spacing.sectionHorizontal / 2
}px`};
`};
`; `;
export const Section = styled.div.attrs(props => ({ export const Section = styled.div.attrs(props => ({
@ -41,7 +47,6 @@ export const Section = styled.div.attrs(props => ({
width: 100%; width: 100%;
display: block; display: block;
content: ''; content: '';
border-bottom: 1px solid rgba(0, 0, 0, 0.2);
} }
`) || `) ||
''} ''}
@ -58,6 +63,13 @@ export const RightPanel = styled.div`
padding: ${props => padding: ${props =>
`${props.theme.spacing.sectionVertical}px ${props.theme.spacing.sectionHorizontal}px`}; `${props.theme.spacing.sectionVertical}px ${props.theme.spacing.sectionHorizontal}px`};
`}; `};
${media.lessThan('small', true)`
width: 100%;
padding: ${props =>
`${props.theme.spacing.sectionVertical / 2}px ${
props.theme.spacing.sectionHorizontal / 2
}px`};
`};
`; `;
export const DarkRightPanel = styled(RightPanel)` export const DarkRightPanel = styled(RightPanel)`

View File

@ -39,6 +39,9 @@ export const StyledPre = styled(PrismDiv).attrs({
font-size: ${props => props.theme.typography.code.fontSize}; font-size: ${props => props.theme.typography.code.fontSize};
overflow-x: auto; overflow-x: auto;
margin: 0; margin: 0;
padding: 10px;
border-radius: 4px;
background-color: rgb(50, 63, 75);
contain: content;
white-space: ${({ theme }) => (theme.typography.code.wrap ? 'pre-wrap' : 'pre')}; white-space: ${({ theme }) => (theme.typography.code.wrap ? 'pre-wrap' : 'pre')};
`; `;

View File

@ -6,70 +6,59 @@ import styled from '../styled-components';
export { Tab, TabList, TabPanel } from 'react-tabs'; export { Tab, TabList, TabPanel } from 'react-tabs';
export const Tabs = styled(ReactTabs)` export const Tabs = styled(ReactTabs)`
padding: 10px 20px 20px;
color: rgb(245, 247, 250);
border-radius: 0 0 4px 4px;
background-color: rgb(82, 96, 109);
> ul { > ul {
list-style: none; list-style: none;
padding: 0; padding: 0;
margin: 0; margin: 0 0 10px;
margin: 0 -5px; border-bottom: 4px solid rgb(97, 110, 124);
> li { > li {
padding: 5px 10px; padding: 5px 10px;
display: inline-block; display: inline-block;
background-color: ${({ theme }) => theme.codeBlock.backgroundColor}; background-color: rgb(82, 96, 109);
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: ${({ theme }) => darken(theme.colors.tonalOffset, theme.rightPanel.textColor)};
margin: 0
${({ theme }) => `${theme.spacing.unit}px ${theme.spacing.unit}px ${theme.spacing.unit}px`};
border: 1px solid ${({ theme }) => darken(0.05, theme.codeBlock.backgroundColor)};
border-radius: 5px;
min-width: 60px; min-width: 60px;
font-size: 0.9em; font-size: 0.9em;
font-weight: bold; font-weight: bold;
&.react-tabs__tab--selected { &.react-tabs__tab--selected {
color: ${props => props.theme.colors.text.primary}; color: white;
background: ${({ theme }) => theme.rightPanel.textColor}; background: rgb(50, 63, 75);
&:focus { border-bottom: 4px solid rgb(89, 195, 255);
outline: auto; margin-bottom: -4px;
}
} }
&:only-child { &:only-child {
flex: none; flex: none;
min-width: 100px; min-width: 100px;
} }
&.tab-success {
color: ${props => props.theme.colors.responses.success.tabTextColor};
} }
&.tab-redirect { > li:first-of-type {
color: ${props => props.theme.colors.responses.redirect.tabTextColor}; border-top-left-radius: 4px;
} }
&.tab-info { > li:last-of-type {
color: ${props => props.theme.colors.responses.info.tabTextColor}; border-top-right-radius: 4px;
}
&.tab-error {
color: ${props => props.theme.colors.responses.error.tabTextColor};
}
} }
} }
> .react-tabs__tab-panel { > .react-tabs__tab-panel {
background: ${({ theme }) => theme.codeBlock.backgroundColor}; background: ${({ theme }) => theme.codeBlock.backgroundColor};
& > div, & > div,
& > pre { & > pre {
padding: ${props => props.theme.spacing.unit * 4}px; margin-top: 10px;
margin: 0;
} }
& > div > pre { & > div > pre {
padding: 0; padding: 10px;
} }
} }
`; `;
@ -101,7 +90,7 @@ export const SmallTabs = styled(Tabs)`
> .react-tabs__tab-panel { > .react-tabs__tab-panel {
& > div, & > div,
& > pre { & > pre {
padding: ${props => props.theme.spacing.unit * 2}px 0; padding: ${props => props.theme.spacing.unit * 2}px 10px;
} }
} }
`; `;

View File

@ -3,7 +3,7 @@ import styled from '../../styled-components';
export const OperationEndpointWrap = styled.div` export const OperationEndpointWrap = styled.div`
cursor: pointer; cursor: pointer;
position: relative; position: relative;
margin-bottom: 5px; margin-bottom: 10px;
`; `;
export const ServerRelativeURL = styled.span` export const ServerRelativeURL = styled.span`
@ -21,9 +21,8 @@ export const EndpointInfo = styled.button<{ $expanded?: boolean; $inverted?: boo
text-align: left; text-align: left;
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')};
background-color: ${props => background-color: rgb(50, 63, 75);
props.$inverted ? 'transparent' : props.theme.codeBlock.backgroundColor};
display: flex; display: flex;
white-space: nowrap; white-space: nowrap;
align-items: center; align-items: center;
@ -54,6 +53,7 @@ export const HttpVerb = styled.span.attrs((props: { type: string; $compact?: boo
text-transform: uppercase; text-transform: uppercase;
font-family: ${props => props.theme.typography.headings.fontFamily}; font-family: ${props => props.theme.typography.headings.fontFamily};
margin: 0; margin: 0;
border-radius: 16px;
`; `;
export const ServersOverlay = styled.div<{ $expanded: boolean }>` export const ServersOverlay = styled.div<{ $expanded: boolean }>`

View File

@ -9,7 +9,6 @@ import {
import { FieldDetails } from './FieldDetails'; import { FieldDetails } from './FieldDetails';
import { import {
InnerPropertiesWrap, InnerPropertiesWrap,
PropertyBullet,
PropertyCellWithInner, PropertyCellWithInner,
PropertyDetailsCell, PropertyDetailsCell,
PropertyNameCell, PropertyNameCell,
@ -74,7 +73,6 @@ export class Field extends React.Component<FieldProps> {
kind={kind} kind={kind}
title={name} title={name}
> >
<PropertyBullet />
<button <button
onClick={this.toggle} onClick={this.toggle}
onKeyPress={this.handleKeyPress} onKeyPress={this.handleKeyPress}
@ -91,7 +89,6 @@ export class Field extends React.Component<FieldProps> {
</ClickablePropertyNameCell> </ClickablePropertyNameCell>
) : ( ) : (
<PropertyNameCell className={deprecated ? 'deprecated' : undefined} kind={kind} title={name}> <PropertyNameCell className={deprecated ? 'deprecated' : undefined} kind={kind} title={name}>
<PropertyBullet />
{!hidePropertiesPrefix && {!hidePropertiesPrefix &&
fieldParentsName.map( fieldParentsName.map(
name => name + '.\u200B', // zero-width space, a special character is used for correct line breaking name => name + '.\u200B', // zero-width space, a special character is used for correct line breaking

View File

@ -10,7 +10,10 @@ export const jsonStyles = css`
font-size: ${props => props.theme.typography.code.fontSize}; font-size: ${props => props.theme.typography.code.fontSize};
white-space: ${({ theme }) => (theme.typography.code.wrap ? 'pre-wrap' : 'pre')}; white-space: ${({ theme }) => (theme.typography.code.wrap ? 'pre-wrap' : 'pre')};
border-radius: 4px;
contain: content; contain: content;
background-color: rgb(50, 63, 75);
padding: 10px;
overflow-x: auto; overflow-x: auto;
.callback-function { .callback-function {

View File

@ -35,6 +35,9 @@ export const StyledMarkdownBlock = styled(
&:last-child { &:last-child {
margin-bottom: 0; margin-bottom: 0;
} }
&:first-child {
margin-top: 0;
}
} }
${({ $compact }) => ${({ $compact }) =>

View File

@ -3,7 +3,7 @@ import * as React from 'react';
import { DropdownOption, DropdownProps } from '../../common-elements/Dropdown'; import { DropdownOption, DropdownProps } from '../../common-elements/Dropdown';
import { MediaContentModel, MediaTypeModel, SchemaModel } from '../../services/models'; import { MediaContentModel, MediaTypeModel, SchemaModel } from '../../services/models';
import { DropdownLabel, DropdownWrapper } from '../PayloadSamples/styled.elements'; import { DropdownWrapper } from '../PayloadSamples/styled.elements';
export interface MediaTypeChildProps { export interface MediaTypeChildProps {
schema: SchemaModel; schema: SchemaModel;
@ -41,14 +41,7 @@ export class MediaTypesSwitch extends React.Component<MediaTypesSwitchProps> {
}); });
const Wrapper = ({ children }) => const Wrapper = ({ children }) =>
this.props.withLabel ? ( this.props.withLabel ? <DropdownWrapper>{children}</DropdownWrapper> : children;
<DropdownWrapper>
<DropdownLabel>Content type</DropdownLabel>
{children}
</DropdownWrapper>
) : (
children
);
return ( return (
<> <>

View File

@ -13,6 +13,7 @@ import { Markdown } from '../Markdown/Markdown';
import { ConstraintsView } from '../Fields/FieldConstraints'; import { ConstraintsView } from '../Fields/FieldConstraints';
import { RequiredLabel } from '../../common-elements/fields'; import { RequiredLabel } from '../../common-elements/fields';
import styled from '../../styled-components'; import styled from '../../styled-components';
import { ParameterDescriptionWrap } from './styled.elements';
function safePush(obj, prop, item) { function safePush(obj, prop, item) {
if (!obj[prop]) { if (!obj[prop]) {
@ -101,7 +102,11 @@ export function BodyContent(props: {
{({ schema }) => { {({ schema }) => {
return ( return (
<> <>
{description !== undefined && <Markdown source={description} />} {description !== undefined && <p></p> && (
<ParameterDescriptionWrap>
<Markdown source={description} />
</ParameterDescriptionWrap>
)}
{schema?.type === 'object' && ( {schema?.type === 'object' && (
<ConstraintsView constraints={schema?.constraints || []} /> <ConstraintsView constraints={schema?.constraints || []} />
)} )}

View File

@ -0,0 +1,5 @@
import styled from '../../styled-components';
export const ParameterDescriptionWrap = styled.div`
padding-bottom: 10px;
`;

View File

@ -6,7 +6,7 @@ import { DropdownOption, DropdownProps } from '../../common-elements';
import { MediaTypeModel } from '../../services/models'; import { MediaTypeModel } from '../../services/models';
import { Markdown } from '../Markdown/Markdown'; import { Markdown } from '../Markdown/Markdown';
import { Example } from './Example'; import { Example } from './Example';
import { DropdownLabel, DropdownWrapper, NoSampleLabel } from './styled.elements'; import { DropdownWrapper, NoSampleLabel } from './styled.elements';
export interface PayloadSamplesProps { export interface PayloadSamplesProps {
mediaType: MediaTypeModel; mediaType: MediaTypeModel;
@ -54,7 +54,6 @@ export class MediaTypeSamples extends React.Component<PayloadSamplesProps, Media
return ( return (
<SamplesWrapper> <SamplesWrapper>
<DropdownWrapper> <DropdownWrapper>
<DropdownLabel>Example</DropdownLabel>
{this.props.renderDropdown({ {this.props.renderDropdown({
value: options[activeIdx].value, value: options[activeIdx].value,
options, options,

View File

@ -4,12 +4,13 @@ import { Dropdown } from '../../common-elements/Dropdown';
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: rgb(50, 63, 75);
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};
font-size: 0.929em; font-size: 0.929em;
line-height: 1.5em; line-height: 1.5em;
border-radius: 4px;
`; `;
export const DropdownLabel = styled.span` export const DropdownLabel = styled.span`
@ -20,10 +21,11 @@ export const DropdownLabel = styled.span`
top: -11px; top: -11px;
left: 12px; left: 12px;
font-weight: ${({ theme }) => theme.typography.fontWeightBold}; font-weight: ${({ theme }) => theme.typography.fontWeightBold};
color: ${({ theme }) => transparentize(0.3, theme.rightPanel.textColor)}; color: ${({ theme }) => transparentize(0.1, theme.rightPanel.textColor)};
`; `;
export const DropdownWrapper = styled.div` export const DropdownWrapper = styled.div`
margin-top: 15px;
position: relative; position: relative;
`; `;
@ -39,15 +41,16 @@ 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: rgb(50, 63, 75);
border: none; border: none;
padding: 0.9em 1.6em 0.9em 0.9em; padding: 0.9em 1.6em 0.9em 0.9em;
border-radius: 4px;
overflow: hidden;
box-shadow: none; box-shadow: none;
&:hover, &:hover,
&:focus-within { &:focus-within {
border: none; border: none;
box-shadow: none; box-shadow: none;
background-color: ${({ theme }) => transparentize(0.3, theme.rightPanel.backgroundColor)};
} }
`; `;

View File

@ -7,6 +7,7 @@ import { SourceCodeWithCopy } from '../SourceCode/SourceCode';
import { RightPanelHeader, Tab, TabList, TabPanel, Tabs } from '../../common-elements'; import { RightPanelHeader, Tab, TabList, TabPanel, Tabs } from '../../common-elements';
import { OptionsContext } from '../OptionsProvider'; import { OptionsContext } from '../OptionsProvider';
import { l } from '../../services/Labels'; import { l } from '../../services/Labels';
import { RequestSamplesWrap } from './styled.elements';
export interface RequestSamplesProps { export interface RequestSamplesProps {
operation: OperationModel; operation: OperationModel;
@ -26,7 +27,7 @@ export class RequestSamples extends React.Component<RequestSamplesProps> {
const hideTabList = samples.length === 1 ? this.context.hideSingleRequestSampleTab : false; const hideTabList = samples.length === 1 ? this.context.hideSingleRequestSampleTab : false;
return ( return (
(hasSamples && ( (hasSamples && (
<div> <RequestSamplesWrap>
<RightPanelHeader> {l('requestSamples')} </RightPanelHeader> <RightPanelHeader> {l('requestSamples')} </RightPanelHeader>
<Tabs defaultIndex={0}> <Tabs defaultIndex={0}>
@ -49,7 +50,7 @@ export class RequestSamples extends React.Component<RequestSamplesProps> {
</TabPanel> </TabPanel>
))} ))}
</Tabs> </Tabs>
</div> </RequestSamplesWrap>
)) || )) ||
null null
); );

View File

@ -0,0 +1,8 @@
import styled from '../../styled-components';
export const RequestSamplesWrap = styled.div`
position: relative;
margin-bottom: 10px;
background-color: rgb(82, 96, 109);
border-radius: 4px;
`;

View File

@ -6,6 +6,7 @@ import { OperationModel } from '../../services/models';
import { RightPanelHeader, Tab, TabList, TabPanel, Tabs } from '../../common-elements'; import { RightPanelHeader, Tab, TabList, TabPanel, Tabs } from '../../common-elements';
import { PayloadSamples } from '../PayloadSamples/PayloadSamples'; import { PayloadSamples } from '../PayloadSamples/PayloadSamples';
import { l } from '../../services/Labels'; import { l } from '../../services/Labels';
import { ResponseSamplesWrap } from './styled.elements';
export interface ResponseSamplesProps { export interface ResponseSamplesProps {
operation: OperationModel; operation: OperationModel;
@ -23,7 +24,7 @@ export class ResponseSamples extends React.Component<ResponseSamplesProps> {
return ( return (
(responses.length > 0 && ( (responses.length > 0 && (
<div> <ResponseSamplesWrap>
<RightPanelHeader> {l('responseSamples')} </RightPanelHeader> <RightPanelHeader> {l('responseSamples')} </RightPanelHeader>
<Tabs defaultIndex={0}> <Tabs defaultIndex={0}>
@ -42,7 +43,7 @@ export class ResponseSamples extends React.Component<ResponseSamplesProps> {
</TabPanel> </TabPanel>
))} ))}
</Tabs> </Tabs>
</div> </ResponseSamplesWrap>
)) || )) ||
null null
); );

View File

@ -0,0 +1,8 @@
import styled from '../../styled-components';
export const ResponseSamplesWrap = styled.div`
position: relative;
margin-bottom: 10px;
background-color: rgb(82, 96, 109);
border-radius: 4px;
`;

View File

@ -3,7 +3,7 @@ import { observer } from 'mobx-react';
import type { ResponseModel, MediaTypeModel } from '../../services/models'; import type { ResponseModel, MediaTypeModel } from '../../services/models';
import { ResponseDetails } from './ResponseDetails'; import { ResponseDetails } from './ResponseDetails';
import { ResponseDetailsWrap, StyledResponseTitle } from './styled.elements'; import { ResponseDetailsWrap, ResponseWrap, StyledResponseTitle } from './styled.elements';
export interface ResponseViewProps { export interface ResponseViewProps {
response: ResponseModel; response: ResponseModel;
@ -28,7 +28,7 @@ export const ResponseView = observer(({ response }: ResponseViewProps): React.Re
); );
return ( return (
<div> <ResponseWrap $type={type}>
<StyledResponseTitle <StyledResponseTitle
onClick={() => response.toggle()} onClick={() => response.toggle()}
type={type} type={type}
@ -42,6 +42,6 @@ export const ResponseView = observer(({ response }: ResponseViewProps): React.Re
<ResponseDetails response={response} /> <ResponseDetails response={response} />
</ResponseDetailsWrap> </ResponseDetailsWrap>
)} )}
</div> </ResponseWrap>
); );
}); });

View File

@ -1,6 +1,6 @@
import * as React from 'react'; import * as React from 'react';
import { Code } from './styled.elements'; import { Code, ResponseTitleWrap } from './styled.elements';
import { ShelfIcon } from '../../common-elements'; import { ShelfIcon } from '../../common-elements';
import { Markdown } from '../Markdown/Markdown'; import { Markdown } from '../Markdown/Markdown';
@ -16,7 +16,6 @@ export interface ResponseTitleProps {
function ResponseTitleComponent({ function ResponseTitleComponent({
title, title,
type,
empty, empty,
code, code,
opened, opened,
@ -30,16 +29,18 @@ function ResponseTitleComponent({
aria-expanded={opened} aria-expanded={opened}
disabled={empty} disabled={empty}
> >
<ResponseTitleWrap>
<Code>{code} </Code>
<Markdown compact={true} inline={true} source={title} />
</ResponseTitleWrap>
{!empty && ( {!empty && (
<ShelfIcon <ShelfIcon
size={'1.5em'} size={'1.3em'}
color={type} color={'rgb(102, 102, 102)'}
direction={opened ? 'down' : 'right'} direction={opened ? 'down' : 'right'}
float={'left'} float={'left'}
/> />
)} )}
<Code>{code} </Code>
<Markdown compact={true} inline={true} source={title} />
</button> </button>
); );
} }

View File

@ -3,26 +3,24 @@ import styled from '../../styled-components';
import { ResponseTitle } from './ResponseTitle'; import { ResponseTitle } from './ResponseTitle';
export const StyledResponseTitle = styled(ResponseTitle)` export const StyledResponseTitle = styled(ResponseTitle)`
display: block; display: flex;
border: 0; font-size: 14px;
justify-content: space-between;
align-items: center;
white-space: normal;
width: 100%; width: 100%;
text-align: left; text-align: left;
padding: 10px; padding: 10px 20px;
border-radius: 2px; border-radius: 4px;
margin-bottom: 4px; background: none;
border: none;
line-height: 1.5em; line-height: 1.5em;
cursor: pointer; cursor: pointer;
color: ${props => props.theme.colors.responses[props.type].color};
background-color: ${props => props.theme.colors.responses[props.type].backgroundColor};
&:focus {
outline: auto ${props => props.theme.colors.responses[props.type].color};
}
${props => ${props =>
(props.empty && (props.empty &&
` `
cursor: default; cursor: default;
&::before { &::after {
content: "—"; content: "—";
font-weight: bold; font-weight: bold;
width: 1.5em; width: 1.5em;
@ -38,7 +36,10 @@ cursor: default;
`; `;
export const ResponseDetailsWrap = styled.div` export const ResponseDetailsWrap = styled.div`
padding: 10px; padding: 20px;
background-color: rgb(255, 255, 255);
border-radius: 0 0 4px 4px;
overflow-x: auto;
`; `;
export const HeadersCaption = styled(UnderlinedHeader).attrs({ export const HeadersCaption = styled(UnderlinedHeader).attrs({
@ -52,3 +53,15 @@ export const HeadersCaption = styled(UnderlinedHeader).attrs({
export const Code = styled.strong` export const Code = styled.strong`
vertical-align: top; vertical-align: top;
`; `;
export const ResponseTitleWrap = styled.div`
display: flex;
gap: 5px;
align-items: baseline;
`;
export const ResponseWrap = styled.div<{ $type: string }>`
border: 1px solid ${props => props.theme.colors.responses[props.$type].color};
background-color: ${props => props.theme.colors.responses[props.$type].backgroundColor};
border-radius: 4px;
margin-bottom: 10px;
`;

View File

@ -10,6 +10,7 @@ import { ObjectSchema } from './ObjectSchema';
const PaddedSchema = styled.div` const PaddedSchema = styled.div`
padding-left: ${({ theme }) => theme.spacing.unit * 2}px; padding-left: ${({ theme }) => theme.spacing.unit * 2}px;
padding-top: ${({ theme }) => theme.spacing.unit * 2}px;
`; `;
export class ArraySchema extends React.PureComponent<SchemaProps> { export class ArraySchema extends React.PureComponent<SchemaProps> {

View File

@ -58,7 +58,7 @@ export function SecurityRequirements(props: SecurityRequirementsProps) {
operationSecuritySchemes.map((scheme, idx) => ( operationSecuritySchemes.map((scheme, idx) => (
<SecurityDetailsStyle key={idx}> <SecurityDetailsStyle key={idx}>
<h5> <h5>
<LockIcon /> {AUTH_TYPES[scheme.type] || scheme.type}: {scheme.id} <LockIcon /> {AUTH_TYPES[scheme.type] || scheme.type}: {scheme.displayName}
</h5> </h5>
<Markdown source={scheme.description || ''} /> <Markdown source={scheme.description || ''} />
<SecurityDetails <SecurityDetails

View File

@ -102,6 +102,7 @@ export const Wrap = styled.div<{ $expanded?: boolean }>`
width: 100%; width: 100%;
display: flex; display: flex;
margin: 1em 0; margin: 1em 0;
padding-bottom: 0.8em;
flex-direction: ${p => (p.$expanded ? 'column' : 'row')}; flex-direction: ${p => (p.$expanded ? 'column' : 'row')};
${media.lessThan('small')` ${media.lessThan('small')`
flex-direction: column; flex-direction: column;

View File

@ -8,7 +8,6 @@ import { MenuItems } from './MenuItems';
import { PerfectScrollbarWrap } from '../../common-elements/perfect-scrollbar'; import { PerfectScrollbarWrap } from '../../common-elements/perfect-scrollbar';
import { RedocAttribution } from './styled.elements'; import { RedocAttribution } from './styled.elements';
import RedoclyLogo from './Logo';
@observer @observer
export class SideMenu extends React.Component<{ menu: MenuStore; className?: string }> { export class SideMenu extends React.Component<{ menu: MenuStore; className?: string }> {
@ -29,7 +28,6 @@ export class SideMenu extends React.Component<{ menu: MenuStore; className?: str
<MenuItems items={store.items} onActivate={this.activate} root={true} /> <MenuItems items={store.items} onActivate={this.activate} root={true} />
<RedocAttribution> <RedocAttribution>
<a target="_blank" rel="noopener noreferrer" href="https://redocly.com/redoc/"> <a target="_blank" rel="noopener noreferrer" href="https://redocly.com/redoc/">
<RedoclyLogo />
API docs by Redocly API docs by Redocly
</a> </a>
</RedocAttribution> </RedocAttribution>

View File

@ -183,7 +183,7 @@ export const RedocAttribution = styled.div`
position: fixed; position: fixed;
width: ${theme.sidebar.width}; width: ${theme.sidebar.width};
bottom: 0; bottom: 0;
background: ${theme.sidebar.backgroundColor}; opacity: 0.5;
a, a,
a:visited, a:visited,

View File

@ -21,9 +21,7 @@ export class MenuBuilder {
const items: ContentItemModel[] = []; const items: ContentItemModel[] = [];
const tags = [...(spec.tags || [])]; const tags = [...(spec.tags || [])];
const hasAutogenerated = tags.find( const hasAutogenerated = tags.find(tag => tag?.name === schemaDefinitionsTagName);
tag => tag?.name === schemaDefinitionsTagName,
);
if (!hasAutogenerated && schemaDefinitionsTagName) { if (!hasAutogenerated && schemaDefinitionsTagName) {
tags.push({ name: schemaDefinitionsTagName }); tags.push({ name: schemaDefinitionsTagName });