Skip to content

Commit

Permalink
perf(Docs): optimize performance
Browse files Browse the repository at this point in the history
  • Loading branch information
levithomason authored and Alexander Fedyashov committed Aug 20, 2017
1 parent 4f36ccd commit 7fc77df
Show file tree
Hide file tree
Showing 23 changed files with 436 additions and 122 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import PropTypes from 'prop-types'
import React from 'react'
import { Menu, Transition } from 'semantic-ui-react'

import { updateForKeys } from 'docs/app/HOC'
import ComponentControlsCopyLink from './ComponentControlsCopyLink'
import ComponentControlsEditCode from './ComponentControlsEditCode'
import ComponentControlsMaximize from './ComponentControlsMaximize'
import ComponentControlsShowHtml from './ComponentControlsShowHtml'

const ComponentControls = (props) => {
const {
anchorName, showHTML, showCode,
onCopyLink, onShowHTML, onShowCode,
visible,
} = props

return (
<Transition
transitionOnMount
visible={!!visible}
unmountOnHide
>
{/* Heads up! Don't remove this `div`, visible Transition applies `display: block`,
while Menu should have `display: inline-flex`
*/}
<div>
<Menu
color='green'
compact
icon
size='small'
text
>
<ComponentControlsCopyLink
anchorName={anchorName}
onClick={onCopyLink}
/>
<ComponentControlsMaximize anchorName={anchorName} />
<ComponentControlsShowHtml
active={showHTML}
onClick={onShowHTML}
/>
<ComponentControlsEditCode
active={showCode}
onClick={onShowCode}
/>
</Menu>
</div>
</Transition>
)
}

ComponentControls.propTypes = {
anchorName: PropTypes.string,
onCopyLink: PropTypes.func,
onShowCode: PropTypes.func,
onShowHTML: PropTypes.func,
showCode: PropTypes.bool,
showHTML: PropTypes.bool,
visible: PropTypes.bool,
}

export default updateForKeys(['showCode', 'showHTML', 'visible'])(ComponentControls)
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import PropTypes from 'prop-types'
import React, { Component } from 'react'
import { Icon, Menu } from 'semantic-ui-react'

import ComponentControlsToolTip from './ComponentControlsToolTip'

export default class ComponentControlsCopyLink extends Component {
state = {}

static propTypes = {
anchorName: PropTypes.string,
onClick: PropTypes.func,
}

shouldComponentUpdate(nextProps, nextState) {
return this.state.active !== nextState.active
}

componentDidMount() {
this.mounted = true
}

componentWillUnmount() {
this.mounted = false
}

handleClick = (e) => {
const { onClick } = this.props

e.preventDefault()
onClick()

this.setState({ active: true })
setTimeout(this.resetActive, 3000)
}

resetActive = () => this.mounted && this.setState({ active: false })

render() {
const { anchorName } = this.props
const { active } = this.state

return (
<ComponentControlsToolTip content={active ? ' Copied Link!' : 'Direct link'}>
<Menu.Item href={`#${anchorName}`} onClick={this.handleClick}>
<Icon
color={active ? 'green' : 'grey'}
fitted
name='linkify'
size='large'
/>
</Menu.Item>
</ComponentControlsToolTip>
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import PropTypes from 'prop-types'
import React from 'react'
import { Icon, Menu } from 'semantic-ui-react'

import { updateForKeys } from 'docs/app/HOC'
import ComponentControlsToolTip from './ComponentControlsToolTip'

const ComponentControlsEditCode = ({ active, onClick }) => (
<ComponentControlsToolTip content='Edit Code'>
<Menu.Item active={active} onClick={onClick}>
<Icon
color={active ? 'green' : 'grey'}
fitted
name='code'
size='large'
/>
</Menu.Item>
</ComponentControlsToolTip>
)

ComponentControlsEditCode.propTypes = {
active: PropTypes.bool,
onClick: PropTypes.func,
}

export default updateForKeys(['active'])(ComponentControlsEditCode)
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import PropTypes from 'prop-types'
import React from 'react'
import { Icon, Menu } from 'semantic-ui-react'

import { neverUpdate } from 'docs/app/HOC'
import ComponentControlsToolTip from './ComponentControlsToolTip'

const ComponentControlsMaximize = ({ anchorName }) => (
<ComponentControlsToolTip content='Full Screen'>
<Menu.Item href={`/maximize/${anchorName}`} target='_blank'>
<Icon
color='grey'
fitted
name='window maximize'
size='large'
/>
</Menu.Item>
</ComponentControlsToolTip>
)

ComponentControlsMaximize.propTypes = {
anchorName: PropTypes.string,
}

export default neverUpdate(ComponentControlsMaximize)
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import PropTypes from 'prop-types'
import React from 'react'
import { Icon, Menu } from 'semantic-ui-react'

import { updateForKeys } from 'docs/app/HOC'
import ComponentControlsToolTip from './ComponentControlsToolTip'

const ComponentControlsShowHtml = ({ active, onClick }) => (
<ComponentControlsToolTip content='Show HTML'>
<Menu.Item active={active} onClick={onClick}>
<Icon
color={active ? 'green' : 'grey'}
size='large'
name='html5'
fitted
/>
</Menu.Item>
</ComponentControlsToolTip>
)

ComponentControlsShowHtml.propTypes = {
active: PropTypes.bool,
onClick: PropTypes.func,
}

export default updateForKeys(['active'])(ComponentControlsShowHtml)
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import PropTypes from 'prop-types'
import React from 'react'
import { Popup } from 'semantic-ui-react'

const toolTipStyle = {
padding: '0.5em',
textAlign: 'center',
width: 100,
}

const ComponentControlsToolTip = ({ children, content }) => (
<Popup
content={content}
inverted
mouseEnterDelay={800}
position='top center'
size='tiny'
style={toolTipStyle}
trigger={children}
/>
)

ComponentControlsToolTip.propTypes = {
children: PropTypes.node,
content: PropTypes.node,
}

export default ComponentControlsToolTip
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default from './ComponentControls'
2 changes: 1 addition & 1 deletion docs/app/Components/ComponentDoc/ComponentDoc.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import React, { Component } from 'react'
import DocumentTitle from 'react-document-title'
import { Link } from 'react-router-dom'

import ComponentExamples from './ComponentExamples'
import ComponentProps from './ComponentProps'
import ComponentExamples from './ComponentExamples'
import docgenInfo from '../../docgenInfo.json'

import { repoURL } from 'docs/app/utils'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ import { html } from 'js-beautify'
import copyToClipboard from 'copy-to-clipboard'

import { exampleContext, repoURL } from 'docs/app/utils'
import { Divider, Grid, Icon, Header, Menu, Popup } from 'src'
import { Divider, Grid, Header, Menu } from 'src'
import Editor from 'docs/app/Components/Editor/Editor'
import { scrollToAnchor } from 'docs/app/utils'
import ComponentControls from '../ComponentControls'

const babelConfig = {
presets: ['es2015', 'react', 'stage-1'],
Expand Down Expand Up @@ -41,23 +42,6 @@ const errorStyle = {
background: '#fff2f2',
}

const toolTipStyle = { width: 100, textAlign: 'center', padding: '0.5em' }
const ToolTip = ({ children, content }) => (
<Popup
inverted
mouseEnterDelay={800}
position='top center'
size='tiny'
style={toolTipStyle}
trigger={children}
content={content}
/>
)
ToolTip.propTypes = {
children: PropTypes.node,
content: PropTypes.node,
}

/**
* Renders a `component` and the raw `code` that produced it.
* Allows toggling the the raw `code` code block.
Expand Down Expand Up @@ -103,16 +87,15 @@ class ComponentExample extends Component {
history.replace(location.pathname)
}

handleDirectLinkClick = (e) => {
e.preventDefault()
handleDirectLinkClick = () => {
this.setHashAndScroll()

copyToClipboard(location.href)
this.setState({ copiedDirectLink: true })

setTimeout(() => this.setState({ copiedDirectLink: false }), 1000)
}

handleMouseEnter = () => this.setState({ controlsVisible: true })

handleMouseLeave = () => this.setState({ controlsVisible: false })

handleShowCodeClick = (e) => {
e.preventDefault()

Expand Down Expand Up @@ -151,7 +134,7 @@ class ComponentExample extends Component {
getOriginalSourceCode = () => {
const { examplePath } = this.props

if (!this.sourceCode) this.sourceCode = require(`!raw-loader!../../Examples/${examplePath}`)
if (!this.sourceCode) this.sourceCode = require(`!raw-loader!../../../Examples/${examplePath}`)

return this.sourceCode
}
Expand Down Expand Up @@ -393,51 +376,54 @@ class ComponentExample extends Component {

render() {
const { children, description, title } = this.props
const { copiedDirectLink, exampleElement, showCode, showHTML } = this.state
const { controlsVisible, exampleElement, showCode, showHTML } = this.state
const exampleStyle = {}

if (showCode || showHTML || location.hash === `#${this.anchorName}`) {
exampleStyle.boxShadow = '0 0 30px #ccc'
}

return (
<Grid className='docs-example' style={exampleStyle} divided={showCode} columns='1' id={this.anchorName}>
<Grid.Column style={headerColumnStyle}>
{title && <Header as='h3' className='no-anchor' style={titleStyle} content={title} />}
{description && <p style={descriptionStyle}>{description}</p>}
<Menu compact text icon size='small' color='green' className='docs-example-menu'>
<ToolTip content={copiedDirectLink ? ' Copied Link!' : 'Direct link'}>
<Menu.Item href={`#${this.anchorName}`} onClick={this.handleDirectLinkClick}>
<Icon size='large' color='grey' name='linkify' fitted />
</Menu.Item>
</ToolTip>
<ToolTip content='Full Screen'>
<Menu.Item href={`/maximize/${this.anchorName}`} target='_blank'>
<Icon size='large' color='grey' name='window maximize' fitted />
</Menu.Item>
</ToolTip>
<ToolTip content='Show HTML'>
<Menu.Item active={showHTML} onClick={this.handleShowHTMLClick}>
<Icon size='large' color={showHTML ? 'green' : 'grey'} name='html5' fitted />
</Menu.Item>
</ToolTip>
<ToolTip content='Edit Code'>
<Menu.Item active={showCode} onClick={this.handleShowCodeClick}>
<Icon size='large' name='code' fitted />
</Menu.Item>
</ToolTip>
</Menu>
</Grid.Column>
<Grid
className='docs-example'
id={this.anchorName}
onMouseEnter={this.handleMouseEnter}
onMouseLeave={this.handleMouseLeave}
style={exampleStyle}
>
<Grid.Row columns={2}>
<Grid.Column style={headerColumnStyle}>
{title && <Header as='h3' className='no-anchor' style={titleStyle} content={title} />}
{description && <p style={descriptionStyle}>{description}</p>}
</Grid.Column>
<Grid.Column textAlign='right'>
<ComponentControls
anchorName={this.anchorName}
onCopyLink={this.handleDirectLinkClick}
onShowCode={this.handleShowCodeClick}
onShowHTML={this.handleShowHTMLClick}
showCode={showCode}
showHTML={showHTML}
visible={controlsVisible}
/>
</Grid.Column>
</Grid.Row>

<Grid.Row columns={1}>
{children && (
<Grid.Column style={childrenStyle}>
{children}
</Grid.Column>
)}
</Grid.Row>

<Grid.Row columns={1}>
<Grid.Column className={`rendered-example ${this.getKebabExamplePath()}`}>
{exampleElement}
</Grid.Column>
{this.renderJSX()}
{this.renderHTML()}
</Grid.Row>
</Grid>
)
}
Expand Down
1 change: 1 addition & 0 deletions docs/app/Components/ComponentDoc/ComponentExample/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default from './ComponentExample'
Loading

0 comments on commit 7fc77df

Please sign in to comment.