import * as React from 'react'; import { ValidationRule, Validation } from '../../models/Validation'; import { sliderData } from './../../models/slider'; import { Query } from '../../models/query'; export interface SliderProps { label?: string; type?: string; name?: string; validationStates?: { [name: string]: Validation }; placeholder?: string; validationRules?: Array; onOptionClick?: (option: any) => void; required?: boolean; value?: number; onChange?: (name: string, value: number) => void; footerFormatter?: (value: number) => string; sliderData?: sliderData; query?: Query; errorMessage?: { min: string; max: string; }; } type SliderContainer = SliderProps & { render: ( sliderOnChange: (value: string) => void, inputOnBlur: (value: string) => void, inputOnChange: (name: string, value: string) => void, inputOnKeyDown: (value: string, e: React.KeyboardEvent) => void, stepUp: () => void, stepDown: () => void, inputValue: number, errorMessage?: React.ReactNode ) => JSX.Element; }; interface SliderState { inputValue: number; errorMessage?: React.ReactNode; } class Slider extends React.Component { constructor(props: SliderContainer) { super(props); this.state = { inputValue: this.props.value }; } shouldComponentUpdate(nextProps: SliderProps, nextState: SliderState) { return ( this.props.value !== nextProps.value || this.state.inputValue !== nextState.inputValue || this.props.query !== nextProps.query ); } sliderOnChange = (value: string | number) => { let errorMessage: React.ReactNode = ''; if (+value > this.props.sliderData.max) { value = String(this.props.sliderData.max); errorMessage = this.props.errorMessage.max; } if (+value < this.props.sliderData.min) { value = String(this.props.sliderData.min); errorMessage = this.props.errorMessage.min; } this.setState({ inputValue: +value, errorMessage }); this.props.onChange(this.props.name, +value); }; inputOnChange = (name: string, value: string) => { if (isNaN(+value)) return; this.setState({ inputValue: +value }); }; inputOnBlur = (value: string) => { this.sliderOnChange( String(Math.floor(+value / this.props.sliderData.step) * this.props.sliderData.step) ); }; inputOnKeyDown = (value: string, e: React.KeyboardEvent) => { if (e.keyCode === 13) { //enter e.preventDefault(); this.inputOnBlur(value); } }; stepUp = () => { let newValue = this.props.value + this.props.sliderData.step; if (newValue <= this.props.sliderData.max) { this.sliderOnChange(newValue); } }; stepDown = () => { let newValue = this.props.value - this.props.sliderData.step; if (newValue >= this.props.sliderData.min) { this.sliderOnChange(newValue); } }; render() { return this.props.render( this.sliderOnChange, this.inputOnBlur, this.inputOnChange, this.inputOnKeyDown, this.stepUp, this.stepDown, this.state.inputValue, this.state.errorMessage ); } } export default Slider;