summaryrefslogtreecommitdiff
path: root/animism-align/frontend/app/common/slider.component.js
diff options
context:
space:
mode:
authorJules Laplace <julescarbon@gmail.com>2020-07-22 14:05:15 +0200
committerJules Laplace <julescarbon@gmail.com>2020-07-22 14:05:15 +0200
commitef78bc6a084f92b4794e987b5832240d85b6479e (patch)
treeb314b630800db6aa60f28ef0b115625e6ca176db /animism-align/frontend/app/common/slider.component.js
parent85d4cb9addf9ca887d3440b2786665d67d9917c4 (diff)
refactor app using babel module-resolver
Diffstat (limited to 'animism-align/frontend/app/common/slider.component.js')
-rw-r--r--animism-align/frontend/app/common/slider.component.js115
1 files changed, 115 insertions, 0 deletions
diff --git a/animism-align/frontend/app/common/slider.component.js b/animism-align/frontend/app/common/slider.component.js
new file mode 100644
index 0000000..7e42b4d
--- /dev/null
+++ b/animism-align/frontend/app/common/slider.component.js
@@ -0,0 +1,115 @@
+import React, { Component } from 'react'
+import { default as throttle } from 'lodash.throttle'
+
+const SLIDER_THROTTLE_TIME = 1000 / 30
+
+export default class Slider extends Component {
+ state = {
+ value: 0
+ }
+
+ constructor(props){
+ super(props)
+ this.timeout = 0
+ this.handleInput = this.handleInput.bind(this)
+ this.handleRange = this.handleRange.bind(this)
+ this.onChange = throttle(props.onChange, SLIDER_THROTTLE_TIME)
+ }
+ componentDidMount() {
+ let { value } = this.props
+ if (this.props.type === 'int') {
+ value = parseInt(value)
+ }
+ this.setState({ value })
+ }
+ componentDidUpdate(prevProps) {
+ let { value } = this.props
+ if (prevProps.value !== value) {
+ if (this.props.type === 'int') {
+ value = parseInt(value)
+ }
+ this.setState({ value })
+ }
+ }
+ handleInput(e){
+ let { name } = this.props
+ let new_value = e.target.value
+ if (new_value === '') {
+ new_value = this.props.defaultValue || (this.props.max - this.props.min) / 2
+ }
+ else if (this.props.type === 'int') {
+ new_value = parseInt(new_value)
+ }
+ else if (this.props.type === 'odd') {
+ new_value = parseInt(Math.floor(new_value / 2) * 2 + 1)
+ }
+ else {
+ new_value = parseFloat(new_value)
+ }
+ if (this.state.value !== new_value) {
+ this.setState({ value: new_value })
+ this.props.onChange(new_value)
+ }
+ }
+ handleRange(e){
+ let { value: new_value } = e.target
+ if (this.props.type === 'int') {
+ new_value = parseInt(new_value)
+ }
+ else if (this.props.type === 'odd') {
+ new_value = parseInt(Math.floor(new_value / 2) * 2 + 1)
+ }
+ else if (this.props.type === 'list') {
+ new_value = this.props.options[new_value] || this.props.options[0]
+ }
+ else {
+ new_value = parseFloat(new_value)
+ }
+ this.setState({ value: new_value })
+ this.onChange(this.props.name, new_value)
+ }
+ render(){
+ let { name, title } = this.props
+ let value = this.state.value
+ if (typeof value === 'undefined') {
+ value = this.props.min
+ }
+ let text_value = value
+ let step;
+ let min = this.props.min || 0
+ let max = this.props.max || 0
+ if (this.props.type === 'int') {
+ step = 1
+ } else if (this.props.type === 'list') {
+ min = 0
+ max = this.props.options.length - 1
+ step = 1
+ value = this.props.options.indexOf(value)
+ } else {
+ step = (this.props.max - this.props.min) / 100
+ text_value = parseFloat(value).toFixed(2)
+ }
+ return (
+ <label className={this.props.error ? 'slider error' : 'slider'}>
+ <span>{title}</span>
+ <input
+ type='number'
+ min={min}
+ max={max}
+ step={step}
+ value={text_value}
+ onChange={this.handleInput}
+ onBlur={this.handleInput}
+ />
+ <input
+ type='range'
+ min={min}
+ max={max}
+ step={step}
+ value={value}
+ onChange={this.handleRange}
+ />
+ </label>
+ )
+ }
+}