UNPKG

dis-gui-lifetoys

Version:

An extensible, styleable, & React-based controller library inspired by the venerable dat-gui.

129 lines (117 loc) 2.88 kB
'use strict'; import PropTypes, { number } from 'prop-types'; import React, { useState, useContext, useEffect } from 'react'; import { StyleContext } from '../styleContext'; import styled from 'styled-components'; // Needs to be outside component to prevent re-render const StyledRangeInput = styled.input` max-width: ${props => props.$vars.width}; flex: 0; padding: 0; font-size: 12px; cursor: pointer; -webkit-appearance: none; height: 0px; background: ${props => props.$vars.lowlight}; border: 1px solid ${props => props.$vars.lowlight}; box-sizing: border-box; &::-webkit-slider-thumb { appearance: none; padding: 0; margin: 0; -webkit-appearance: none; height: ${props => props.$vars.thumbHeight}; width: ${props => props.$vars.thumbWidth}; border-radius: 0; border: 1px solid ${props => props.$vars.highlight}; background: ${props => props.$vars.lowlight}; } `; export default function RangeInput({ value, min, max, step, decimals, width, thumbHeight, thumbWidth, onChange, }) { const styleContext = useContext(StyleContext); const vars = { width, lowlight: styleContext.lowlight, medlight: styleContext.medlight, highlight: styleContext.highlight, thumbWidth, thumbHeight, }; const truncate = (value) => { if (decimals !== undefined) { return sprintf(`%.${decimals}f`, parseFloat(value)); } return value; }; const [valueState, setValue] = useState(truncate(value)); const handleChangeEvent = (event) => { const newValue = truncate(Math.min(max, Math.max(min, event.target.value))); //console.log('RangeInput.handleChange, newValue:', newValue); setValue(newValue); if (onChange) { onChange(newValue); } }; return ( <StyledRangeInput type="range" value={value} min={min} max={max} step={step} onChange={handleChangeEvent} $vars={vars} ></StyledRangeInput> ); } RangeInput.propTypes = { value: PropTypes.number.isRequired, min: PropTypes.number.isRequired, max: PropTypes.number.isRequired, step: PropTypes.number, width: PropTypes.string, thumbHeight: PropTypes.string, thumbWidth: PropTypes.string, onChange: PropTypes.func, } RangeInput.defaultProps = { value: 0, min: 0, max: 1, step: 1, width: 'auto', thumbHeight: '10px', thumbWidth: '10px', }; //RangeInput.contextTypes = { //styleContext: PropTypes.object, /*folder: PropTypes.shape({ subscribe: PropTypes.func }),*/ //} /* componentDidMount() { if (this.context.folder) { this.unsubscribeFolder = this.context.folder.subscribe((expanded) => { if (expanded) { this.forceUpdate(); } }) } } componentWillUnmount() { if (this.unsubscribeFolder) { this.unsubscribeFolder(); } } */