UNPKG

avlmap

Version:
155 lines (137 loc) 4.2 kB
import React, {Component} from 'react'; import PropTypes from 'prop-types'; import classnames from 'classnames'; import styled from 'styled-components'; import SliderHandle from './slider-handle'; import SliderBarHandle from './slider-bar-handle'; function noop() {} const StyledRangeSlider = styled.div` position: relative; margin-bottom: 12px; background-color: ${props => props.theme.sliderBarBgd}; height: ${props => props.theme.sliderBarHeight}; `; const SliderWrapper = styled.div` flex-grow: 1; margin-top: ${props => props.isRanged ? 0 : 10}px; `; export default class Slider extends Component { _saveRef = ref => { this.ref = ref; }; slide0Listener = x => { const xPercent = x / this.ref.offsetWidth; const maxDelta = this.props.maxValue - this.props.minValue; const val = xPercent * maxDelta; this.props.onSlider0Change.call(this, val + this.props.value0); }; slide1Listener = x => { if (this.ref) { const xPercent = x / this.ref.offsetWidth; const maxDelta = this.props.maxValue - this.props.minValue; const val = xPercent * maxDelta; this.props.onSlider1Change(val + this.props.value1); } }; sliderBarListener = x => { const xPercent = x / this.ref.offsetWidth; const maxDelta = this.props.maxValue - this.props.minValue; const val = xPercent * maxDelta; const val0 = val + this.props.value0; const val1 = val + this.props.value1; this.props.onSliderBarChange(val0, val1); }; calcHandleLeft0 = (w, l, num) => { return w === 0 ? `calc(${l}% - ${this.props.sliderHandleWidth / 2}px)` : `calc(${l}% - ${this.props.sliderHandleWidth / 2}px)`; }; calcHandleLeft1 = (w, l) => { return this.props.isRanged && w === 0 ? `${l}%` : `calc(${l + w}% - ${this.props.sliderHandleWidth / 2}px)`; }; createSlider = (width, v0Left) => { return ( <div> <StyledRangeSlider className="kg-range-slider"> <SliderHandle className="kg-range-slider__handle" left={this.calcHandleLeft0(width, v0Left)} valueListener={this.slide0Listener} sliderHandleWidth={this.props.sliderHandleWidth} display={this.props.isRanged} /> <SliderHandle className="kg-range-slider__handle" left={this.calcHandleLeft1(width, v0Left)} valueListener={this.slide1Listener} sliderHandleWidth={this.props.sliderHandleWidth} /> <SliderBarHandle width={width} v0Left={v0Left} enableBarDrag={this.props.enableBarDrag} sliderBarListener={this.sliderBarListener} /> </StyledRangeSlider> </div> ); }; render() { const { classSet, isRanged, maxValue, minValue, value1 } = this.props; const value0 = !isRanged && minValue > 0 ? minValue : this.props.value0; const currValDelta = value1 - value0; const maxDelta = maxValue - minValue; const width = currValDelta / maxDelta * 100; const v0Left = (value0 - minValue) / maxDelta * 100; return ( <SliderWrapper className={classnames('kg-slider', {...classSet})} ref={this._saveRef} isRanged={isRanged} > {this.createSlider(width, v0Left)} </SliderWrapper> ); } } Slider.propTypes = { title: PropTypes.string, isRanged: PropTypes.bool, value0: PropTypes.number, value1: PropTypes.number, minValue: PropTypes.number, maxValue: PropTypes.number, sliderHandleWidth: PropTypes.number, onSlider0Change: PropTypes.func, onInput0Change: PropTypes.func, onSlider1Change: PropTypes.func, onInput1Change: PropTypes.func, onSliderBarChange: PropTypes.func, step: PropTypes.number, enableBarDrag: PropTypes.bool }; Slider.defaultProps = { title: '', isRanged: true, value0: 0, value1: 100, minValue: 0, maxValue: 100, step: 1, sliderHandleWidth: 12, enableBarDrag: false, onSlider0Change: noop, onInput0Change: noop, onSlider1Change: noop, onInput1Change: noop, onSliderBarChange: noop, disabled: false }; Slider.ref = undefined;