sc-react-ions
Version:
An open source set of React components that implement Ambassador's Design and UX patterns.
123 lines (103 loc) • 2.8 kB
JavaScript
import React from 'react'
import PropTypes from 'prop-types'
import optclass from '../internal/OptClass'
import style from './style.scss'
class PanelSlider extends React.Component {
constructor(props) {
super(props)
}
static propTypes = {
/**
* The currently active panel
*/
activePanel: PropTypes.number,
/**
* Optional CSS class(es) to be used for local styles (string or array of strings)
*/
optClass: PropTypes.oneOfType([
PropTypes.array,
PropTypes.string
])
}
static defaultProps = {
activePanel: 0,
name: 'PanelSlider'
}
state = {
panels: [],
isTransitioning: false
}
componentWillMount = () => {
this.activatePanel(this.props.activePanel)
}
// No sCU on this component because
// nested child components need to be
// able to update as needed
componentWillReceiveProps = nextProps => {
if (nextProps.activePanel !== this.props.activePanel) {
this.setState({
isTransitioning: true
})
this.activatePanel(nextProps.activePanel)
setTimeout(() => {
this.setState({
isTransitioning: false
})
}, 500)
}
}
getStyle = index => {
let translateValue
if (index === 0) {
translateValue = 0
} else {
translateValue = `-${index}00`
}
return {
'transform': `translateX(${translateValue}%)`
}
}
getPanels = () => {
const panels = []
React.Children.forEach(this.props.children, panel => {
if (React.isValidElement(panel)) {
panels.push(panel)
}
})
return panels
}
activatePanel = activePanel => {
var panels = this.getPanels()
var initialPanels = []
panels.forEach((panel, index) => {
const active = activePanel === index
initialPanels = [...initialPanels, { active }]
})
this.setState({panels: initialPanels})
}
render() {
const isTransitioningClass = this.state.isTransitioning ? style['is-transitioning'] : null
const panelSliderClasses = optclass(style, 'panel-slider', [this.props.optClass, isTransitioningClass])
const panelWrapClasses = optclass(style, 'panel-wrap')
const panels = this.getPanels().map((panel, index) => {
return React.cloneElement(panel, {
key: index,
panelIndex: index,
active: this.state.panels[index].active,
name: this.props.name
})
})
return (
<div className={panelSliderClasses}>
<div className={style['wrapper']}>
<div className={style['inner']}>
<div className={panelWrapClasses} style={this.getStyle(this.props.activePanel)}>
{panels}
</div>
</div>
</div>
</div>
)
}
}
export default PanelSlider