Add READMORE button feature.

This commit is contained in:
exoego 2018-11-11 11:03:47 +09:00
parent ebe8d3f68c
commit 884031b60c
2 changed files with 95 additions and 1 deletions

View 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>
);
}
}

View File

@ -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>
)}