UNPKG

react-awesome-query-builder-pd

Version:

User-friendly query builder for React. Demo: https://ukrbublik.github.io/react-awesome-query-builder

123 lines (108 loc) 2.92 kB
import React from "react" import Slider from "@mui/material/Slider" import TextField from "@mui/material/TextField" import FormControl from "@mui/material/FormControl" import { makeStyles } from "@mui/styles" const useStyles = makeStyles((theme) => ({ root: { display: "flex", alignItems: "center" } })) export default (props) => { const { config, placeholder, customProps, value, setValue, min, max, step, marks, readonly } = props const classes = useStyles() const { defaultSliderWidth } = config.settings const handleSliderChange = (_e, newValue) => { setValue(newValue) } const handleInputChange = (e) => { let val = e.target.value if (val === "" || val === null) val = undefined else val = Number(val) setValue(val) } const handleInputBlur = () => { // TIP: Fix if typed value out of range in input if (value < min) { setValue(min) } else if (value > max) { setValue(max) } } const { width, ...rest } = customProps || {} const customInputProps = rest.input || {} const customSliderProps = rest.slider || rest // TIP: Can't pass undefined to MUI, cause it means uncontrolled component use. // For empty value input needs "", slider needs null or 0 const inputValue = typeof value === "number" ? value : "" const sliderValue = typeof value === "number" ? value : null // marks example: { 0: "0%", 100: React.createElement('strong', null, "100%") } const muiMarks = marks ? Boolean(Object.keys(marks).map((v) => ({ value: v, label: marks[v] }))) : false const InputCmp = ( <TextField type="number" value={inputValue} placeholder={placeholder} InputProps={{ readOnly: readonly }} inputProps={{ min: min, max: max, step: step }} disabled={readonly} onChange={handleInputChange} onBlur={handleInputBlur} {...customInputProps} /> ) const SliderCmp = ( <Slider value={sliderValue} onChange={handleSliderChange} disabled={readonly} min={min} max={max} step={step} marks={muiMarks} valueLabelDisplay="auto" {...customSliderProps} /> ) const stylesWrapper = { display: "inline-flex", alignItems: "center" } const stylesInputWrapper = { marginLeft: "5px" } const stylesSliderWrapper = { marginLeft: "5px", paddingLeft: "12px", marginBottom: muiMarks && "-16px", width: width || defaultSliderWidth } return ( <FormControl> <div className={classes.root}> <div style={stylesInputWrapper}>{InputCmp}</div> <div style={stylesSliderWrapper}>{SliderCmp}</div> </div> </FormControl> ) }