Skip to content

Commit

Permalink
fix(ComponentExample): clipboard and active state (#2796)
Browse files Browse the repository at this point in the history
  • Loading branch information
levithomason authored May 18, 2018
1 parent 958716b commit 447f96b
Showing 1 changed file with 66 additions and 42 deletions.
108 changes: 66 additions & 42 deletions docs/app/Components/ComponentDoc/ComponentExample/ComponentExample.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import * as Babel from '@babel/standalone'
import _ from 'lodash'
import PropTypes from 'prop-types'
import React, { Component, createElement, isValidElement } from 'react'
import React, { PureComponent, createElement, isValidElement } from 'react'
import { withRouter } from 'react-router'
import { renderToStaticMarkup } from 'react-dom/server'
import { html } from 'js-beautify'
import copyToClipboard from 'copy-to-clipboard'

import { exampleContext, repoURL, scrollToAnchor } from 'docs/app/utils'
import { Divider, Grid, Menu, Visibility } from 'src'
import { shallowEqual } from 'src/lib'
import Editor from 'docs/app/Components/Editor/Editor'
import ComponentControls from '../ComponentControls'
import ComponentExampleTitle from './ComponentExampleTitle'
Expand Down Expand Up @@ -51,7 +50,7 @@ const errorStyle = {
* Renders a `component` and the raw `code` that produced it.
* Allows toggling the the raw `code` code block.
*/
class ComponentExample extends Component {
class ComponentExample extends PureComponent {
static contextTypes = {
onPassed: PropTypes.func,
}
Expand All @@ -68,32 +67,35 @@ class ComponentExample extends Component {
}

componentWillMount() {
const { examplePath, location } = this.props
const { examplePath } = this.props
const sourceCode = this.getOriginalSourceCode()

this.anchorName = _.kebabCase(_.last(examplePath.split('/')))

// show code for direct links to examples
const showCode = this.anchorName === location.hash.replace('#', '')
const exampleElement = this.renderOriginalExample()
const markup = renderToStaticMarkup(exampleElement)

this.setState({
exampleElement,
showCode,
handleMouseLeave: this.handleMouseLeave,
handleMouseMove: this.handleMouseMove,
showCode: this.isActiveHash(),
sourceCode,
markup,
})
}

componentWillReceiveProps(nextProps) {
const isActive = nextProps.location.hash === `#${this.anchorName}`
isActiveState = () => {
const { showCode, showHTML } = this.state

this.setState(() => ({ isActive }))
return showCode || showHTML
}

shouldComponentUpdate(nextProps, nextState) {
return !shallowEqual(this.state, nextState)
isActiveHash = () => this.anchorName === this.props.location.hash.replace('#', '')

updateHash = () => {
if (this.isActiveState()) this.setHashAndScroll()
else if (this.isActiveHash()) this.removeHash()
}

setHashAndScroll = () => {
Expand All @@ -105,47 +107,50 @@ class ComponentExample extends Component {

removeHash = () => {
const { history, location } = this.props

history.replace(location.pathname)

this.setState({
showCode: false,
showHTML: false,
})
}

handleDirectLinkClick = () => {
this.setHashAndScroll()
copyToClipboard(window.location.href)
}

handleMouseMove = _.throttle(
() => {
const { controlsVisible } = this.state
if (controlsVisible) return

this.setState({ controlsVisible: true })
},
200,
{ trailing: false },
)
handleMouseLeave = () => {
this.setState({
isHovering: false,
handleMouseLeave: null,
handleMouseMove: this.handleMouseMove,
})
}

handleMouseLeave = () => this.setState({ controlsVisible: false })
handleMouseMove = () => {
this.setState({
isHovering: true,
handleMouseLeave: this.handleMouseLeave,
handleMouseMove: null,
})
}

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

const { showCode, showHTML } = this.state

this.setState({ showCode: !showCode })
const { showCode } = this.state

if (!showCode) this.setHashAndScroll()
else if (!showHTML) this.removeHash()
this.setState({ showCode: !showCode }, this.updateHash)
}

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

const { showCode, showHTML } = this.state

this.setState({ showHTML: !showHTML })
const { showHTML } = this.state

if (!showHTML) this.setHashAndScroll()
else if (!showCode) this.removeHash()
this.setState({ showHTML: !showHTML }, this.updateHash)
}

handlePass = () => {
Expand All @@ -163,8 +168,8 @@ class ComponentExample extends Component {
resetJSX = () => {
const { sourceCode } = this.state
const original = this.getOriginalSourceCode()
// eslint-disable-next-line no-alert
if (sourceCode !== original && confirm('Lose your changes?')) {
// eslint-disable-line no-alert
this.setState({ sourceCode: original })
this.renderSourceCode()
}
Expand Down Expand Up @@ -289,8 +294,7 @@ class ComponentExample extends Component {
}, 100)

handleChangeCode = (sourceCode) => {
this.setState({ sourceCode })
this.renderSourceCode()
this.setState({ sourceCode }, this.renderSourceCode)
}

setGitHubHrefs = () => {
Expand Down Expand Up @@ -432,20 +436,40 @@ class ComponentExample extends Component {

render() {
const { children, description, suiVersion, title } = this.props
const { controlsVisible, exampleElement, isActive, showCode, showHTML } = this.state
const {
handleMouseLeave,
handleMouseMove,
exampleElement,
isHovering,
showCode,
showHTML,
} = this.state

const isActive = this.isActiveHash() || this.isActiveState()

const exampleStyle = {
marginBottom: '1em',
boxShadow: isActive && '0 0 30px #ccc',
position: 'relative',
transition: 'box-shadow 200ms, background 200ms',
...(isActive
? {
background: '#fff',
boxShadow: '0 0 30px #ccc',
}
: isHovering && {
background: '#fff',
boxShadow: '0 0 10px #ccc',
zIndex: 1,
}),
}

return (
<Visibility once={false} onTopPassed={this.handlePass} onTopPassedReverse={this.handlePass}>
<Grid
className='docs-example'
padded='vertically'
id={this.anchorName}
onMouseMove={this.handleMouseMove}
onMouseLeave={this.handleMouseLeave}
onMouseLeave={handleMouseLeave}
onMouseMove={handleMouseMove}
style={exampleStyle}
>
<Grid.Row>
Expand All @@ -464,7 +488,7 @@ class ComponentExample extends Component {
onShowHTML={this.handleShowHTMLClick}
showCode={showCode}
showHTML={showHTML}
visible={controlsVisible}
visible={isActive || isHovering}
/>
</Grid.Column>
</Grid.Row>
Expand Down

0 comments on commit 447f96b

Please sign in to comment.