import * as React from 'react'; export interface AccordionSliderDataModel{ img:string; head?:any; } export interface AccordionSliderProps{ visible:boolean; className?:string; data:Array; responsive?:boolean; orientation?:'vertical'|'horizontal'; resize?:number; onItemClick?:()=>void; } export interface AccordionSliderState{ orientation?:string; resize?:number; } export class AccordionSlider extends React.Component{ bb:any; panels:any; panelsCount:number; panelsSpacing:any; isVertical:boolean; constructor(props:AccordionSliderProps){ super(props); this.state = { orientation: props.orientation } this.panelsSpacing = { default: 0, expanded: 0, shrank: 0 } this.setSpacing = this.setSpacing.bind(this); this.expandPanel = this.expandPanel.bind(this); this.calculate = this.calculate.bind(this); this.onResize = this.onResize.bind(this); this.onResize = _.throttle(this.onResize,500); } componentDidMount() { this.panels = (this.refs['panels'] as HTMLElement).querySelectorAll('.as-panel'); this.bb = (this.refs['accordion-slider'] as HTMLElement); this.panelsCount = this.props.data.length; this.isVertical = this.state.orientation == 'vertical'; window.addEventListener('resize',this.onResize); this.onResize(); } componentDidUpdate() { this.isVertical = this.state.orientation == 'vertical'; if(this.props.resize != this.state.resize) { this.setState({ resize: this.props.resize }); setTimeout(() => { this.onResize(); }, 100); } } onResize() { if(this.props.responsive) { let bb = this.bb.getBoundingClientRect(); this.setState({ orientation: bb.width < 450 ? 'vertical' : 'horizontal' }); } this.calculate(); this.setSpacing(); } calculate() { let bb = this.bb.getBoundingClientRect(), imgEl = this.panels[0].querySelector('.as-panel-image img'), imgWidth = imgEl.clientWidth/bb.width*100, imgHeight = imgEl.clientHeight/bb.height*100; this.panelsSpacing = { default: 100/this.panelsCount, expanded: this.isVertical ? imgHeight : imgWidth, shrank: (100 - (this.isVertical ? imgHeight : imgWidth)) / (this.panelsCount-1) } } setSpacing() { for(let i = 0; i < this.panels.length; i++) { this.panels[i].setAttribute('expanded',false); this.panels[i].style[this.isVertical ? 'height' : 'width'] = this.panelsSpacing.default+'%'; this.panels[i].style[!this.isVertical ? 'height' : 'width'] = ''; } } expandPanel(e:any) { let bb = this.bb.getBoundingClientRect(), el = (e.currentTarget as HTMLElement), index = el.getAttribute('data-index'); el.setAttribute('expanded','true'); el.style[this.isVertical ? 'height' : 'width'] = this.panelsSpacing.expanded+'%'; for(let i = 0; i < this.panels.length; i++) { if(i+"" != index) { this.panels[i].style[this.isVertical ? 'height' : 'width'] = this.panelsSpacing.shrank+'%'; this.panels[i].style[!this.isVertical ? 'height' : 'width'] = ''; } } } render(){ let clz = this.props.className || '', props = this.props; return (
{ this.props.data.map((d:any, i:number) => { return (
{ d.head &&
{ d.head }
}
) }) }
); } }