diff --git a/src/common-elements/ReadMore.tsx b/src/common-elements/ReadMore.tsx new file mode 100644 index 00000000..2ff25761 --- /dev/null +++ b/src/common-elements/ReadMore.tsx @@ -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 { + constructor(props: ReadMoreProps) { + super(props); + this.state = { + open: false + }; + } + + toggle = () => { + this.setState(prevState => ({ + open: !prevState.open + })); + }; + + render() { + const { content } = this.props; + + if (!content) { + return + } + + return ( + + + + + {this.state.open ? 'CLOSE' : 'READ MORE'} + + + + + ); + } +} diff --git a/src/components/Operation/Operation.tsx b/src/components/Operation/Operation.tsx index 1283a6ad..025e9d31 100644 --- a/src/components/Operation/Operation.tsx +++ b/src/components/Operation/Operation.tsx @@ -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 = //; + export interface OperationProps { operation: OperationType; } +function splitDescription(description) { + if (!description) { + return ["", ""]; + } else { + // str#split split at all occurence of matched string. + // So "abc" --> ["a", "", "b", "", "c"] + const [head, ...rest] = description.split(ReadmorePattern); + const more = rest.join(""); + return [head, more]; + } +} + @observer export class Operation extends React.Component { render() { @@ -43,6 +58,7 @@ export class Operation extends React.Component { const { name: summary, description, deprecated, externalDocs } = operation; const hasDescription = !!(description || externalDocs); + const [headDescription, moreDescription] = splitDescription(description); return ( {options => ( @@ -55,7 +71,8 @@ export class Operation extends React.Component { {options.pathInMiddlePanel && } {hasDescription && ( - {description !== undefined && } + {description !== undefined && } + {externalDocs && } )}