mirror of
https://github.com/Redocly/redoc.git
synced 2025-08-08 14:14:56 +03:00
Add READMORE button feature.
This commit is contained in:
parent
ebe8d3f68c
commit
884031b60c
77
src/common-elements/ReadMore.tsx
Normal file
77
src/common-elements/ReadMore.tsx
Normal file
|
@ -0,0 +1,77 @@
|
|||
import * as React from 'react';
|
||||
|
||||
import styled from '../styled-components';
|
||||
import {ShelfIcon} from "./shelfs";
|
||||
import {Markdown} from "../components";
|
||||
|
||||
|
||||
export interface ReadMoreProps {
|
||||
content?: string;
|
||||
}
|
||||
|
||||
interface ReadMoreState {
|
||||
open: boolean
|
||||
}
|
||||
|
||||
const ReadMoreWrapper = styled.div`
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
max-height: ${(props: ReadMoreState) => props.open ? 'auto': '5em'};
|
||||
padding-bottom: ${(props: ReadMoreState) => props.open ? '3em' : '1em'};
|
||||
`;
|
||||
|
||||
const ReadMoreButtonBackground = styled.div`
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
background-image: linear-gradient(to bottom, rgba(255,255,255,0.3), white);
|
||||
width: 100%;
|
||||
bottom: 0;
|
||||
padding: ${(props: ReadMoreState) => props.open ? '0': '2em'};
|
||||
`;
|
||||
|
||||
const ReadMoreButton = styled.span`
|
||||
background: #999;
|
||||
color: #fff;
|
||||
padding: 0.3em 0.75em;
|
||||
border-radius: 2px;
|
||||
`;
|
||||
|
||||
export class ReadMore extends React.Component<ReadMoreProps, ReadMoreState> {
|
||||
constructor(props: ReadMoreProps) {
|
||||
super(props);
|
||||
this.state = {
|
||||
open: false
|
||||
};
|
||||
}
|
||||
|
||||
toggle = () => {
|
||||
this.setState(prevState => ({
|
||||
open: !prevState.open
|
||||
}));
|
||||
};
|
||||
|
||||
render() {
|
||||
const { content } = this.props;
|
||||
|
||||
if (!content) {
|
||||
return <ReadMoreWrapper open={false} />
|
||||
}
|
||||
|
||||
return (
|
||||
<ReadMoreWrapper open={this.state.open}>
|
||||
<ReadMoreButtonBackground onClick={this.toggle} open={this.state.open}>
|
||||
<ReadMoreButton>
|
||||
<ShelfIcon
|
||||
size={'1.5em'}
|
||||
color={'white'}
|
||||
direction={this.state.open ? 'up' : 'down'}
|
||||
/>
|
||||
{this.state.open ? 'CLOSE' : 'READ MORE'}
|
||||
</ReadMoreButton>
|
||||
</ReadMoreButtonBackground>
|
||||
<Markdown source={content} />
|
||||
</ReadMoreWrapper>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -19,6 +19,7 @@ import { ResponseSamples } from '../ResponseSamples/ResponseSamples';
|
|||
import { OperationModel as OperationType } from '../../services/models';
|
||||
import styled from '../../styled-components';
|
||||
import { Extensions } from '../Fields/Extensions';
|
||||
import { ReadMore } from "../../common-elements/ReadMore";
|
||||
|
||||
const OperationRow = styled(Row)`
|
||||
backface-visibility: hidden;
|
||||
|
@ -31,10 +32,24 @@ const Description = styled.div`
|
|||
margin-bottom: ${({ theme }) => theme.spacing.unit * 6}px;
|
||||
`;
|
||||
|
||||
const ReadmorePattern = /<!--\s*READMORE\s*-->/;
|
||||
|
||||
export interface OperationProps {
|
||||
operation: OperationType;
|
||||
}
|
||||
|
||||
function splitDescription(description) {
|
||||
if (!description) {
|
||||
return ["", ""];
|
||||
} else {
|
||||
// str#split split at all occurence of matched string.
|
||||
// So "a<!--READMORE-->b<!--READMORE-->c" --> ["a", "<!..>", "b", "<!..>", "c"]
|
||||
const [head, ...rest] = description.split(ReadmorePattern);
|
||||
const more = rest.join("");
|
||||
return [head, more];
|
||||
}
|
||||
}
|
||||
|
||||
@observer
|
||||
export class Operation extends React.Component<OperationProps> {
|
||||
render() {
|
||||
|
@ -43,6 +58,7 @@ export class Operation extends React.Component<OperationProps> {
|
|||
const { name: summary, description, deprecated, externalDocs } = operation;
|
||||
const hasDescription = !!(description || externalDocs);
|
||||
|
||||
const [headDescription, moreDescription] = splitDescription(description);
|
||||
return (
|
||||
<OptionsContext.Consumer>
|
||||
{options => (
|
||||
|
@ -55,7 +71,8 @@ export class Operation extends React.Component<OperationProps> {
|
|||
{options.pathInMiddlePanel && <Endpoint operation={operation} inverted={true} />}
|
||||
{hasDescription && (
|
||||
<Description>
|
||||
{description !== undefined && <Markdown source={description} />}
|
||||
{description !== undefined && <Markdown source={headDescription} />}
|
||||
<ReadMore content={moreDescription}/>
|
||||
{externalDocs && <ExternalDocumentation externalDocs={externalDocs} />}
|
||||
</Description>
|
||||
)}
|
||||
|
|
Loading…
Reference in New Issue
Block a user