@geezee/react-ui
Version:
Modern and minimalist React UI library.
148 lines (131 loc) • 5.67 kB
JavaScript
import _extends from "@babel/runtime/helpers/esm/extends";
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
import _JSXStyle from "styled-jsx/style";
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import useTheme from '../styles/use-theme';
import withDefaults from '../utils/with-defaults';
import useDrag from '../utils/use-drag';
import useCurrentState from '../utils/use-current-state';
import SliderDot from './slider-dot';
import SliderMark from './slider-mark';
var defaultProps = {
initialValue: 0,
step: 1,
min: 0,
max: 100,
disabled: false,
showMarkers: false,
className: ''
};
var getRefWidth = function getRefWidth(elementRef) {
if (!elementRef || !elementRef.current) return 0;
var rect = elementRef.current.getBoundingClientRect();
return rect.width || rect.right - rect.left;
};
var getValue = function getValue(max, min, step, offsetX, railWidth) {
if (offsetX < 0) return min;
if (offsetX > railWidth) return max;
var widthForEachStep = railWidth / (max - min) * step;
if (widthForEachStep <= 0) return min;
var slideDistance = Math.round(offsetX / widthForEachStep) * step + min;
return Number.isInteger(slideDistance) ? slideDistance : Number.parseFloat(slideDistance.toFixed(1));
};
var Slider = function Slider(_ref) {
var disabled = _ref.disabled,
step = _ref.step,
max = _ref.max,
min = _ref.min,
initialValue = _ref.initialValue,
customValue = _ref.value,
onChange = _ref.onChange,
className = _ref.className,
showMarkers = _ref.showMarkers,
props = _objectWithoutProperties(_ref, ["disabled", "step", "max", "min", "initialValue", "value", "onChange", "className", "showMarkers"]);
var theme = useTheme();
var _useState = useState(initialValue),
_useState2 = _slicedToArray(_useState, 2),
value = _useState2[0],
setValue = _useState2[1];
var _useCurrentState = useCurrentState(0),
_useCurrentState2 = _slicedToArray(_useCurrentState, 3),
setSliderWidth = _useCurrentState2[1],
sideWidthRef = _useCurrentState2[2];
var _useCurrentState3 = useCurrentState(0),
_useCurrentState4 = _slicedToArray(_useCurrentState3, 3),
setLastDargOffset = _useCurrentState4[1],
lastDargOffsetRef = _useCurrentState4[2];
var _useState3 = useState(false),
_useState4 = _slicedToArray(_useState3, 2),
isClick = _useState4[0],
setIsClick = _useState4[1];
var sliderRef = useRef(null);
var dotRef = useRef(null);
var currentRatio = useMemo(function () {
return (value - min) / (max - min) * 100;
}, [value, max, min]);
var setLastOffsetManually = function setLastOffsetManually(val) {
var width = getRefWidth(sliderRef);
var shouldOffset = (val - min) / (max - min) * width;
setLastDargOffset(shouldOffset);
};
var updateValue = useCallback(function (offset) {
var currentValue = getValue(max, min, step, offset, sideWidthRef.current);
setValue(currentValue);
onChange && onChange(currentValue);
}, [max, min, step, sideWidthRef]);
var dragHandler = function dragHandler(event) {
if (disabled) return;
var currentOffset = event.currentX - event.startX;
var offset = currentOffset + lastDargOffsetRef.current;
updateValue(offset);
};
var dragStartHandler = function dragStartHandler() {
setIsClick(false);
setSliderWidth(getRefWidth(sliderRef));
};
var dragEndHandler = function dragEndHandler(event) {
if (disabled) return;
var offset = event.currentX - event.startX;
var currentOffset = offset + lastDargOffsetRef.current;
var boundOffset = currentOffset < 0 ? 0 : Math.min(currentOffset, sideWidthRef.current);
setLastDargOffset(boundOffset);
};
var clickHandler = function clickHandler(event) {
if (disabled) return;
if (!sliderRef || !sliderRef.current) return;
setIsClick(true);
setSliderWidth(getRefWidth(sliderRef));
var clickOffset = event.clientX - sliderRef.current.getBoundingClientRect().x;
setLastDargOffset(clickOffset);
updateValue(clickOffset);
};
useDrag(dotRef, dragHandler, dragStartHandler, dragEndHandler);
useEffect(function () {
if (customValue === undefined) return;
if (customValue === value) return;
setValue(customValue);
}, [customValue, value]);
useEffect(function () {
initialValue && setLastOffsetManually(initialValue);
}, []);
return /*#__PURE__*/React.createElement("div", _extends({
onClick: clickHandler,
ref: sliderRef
}, props, {
className: _JSXStyle.dynamic([["3952089332", [disabled ? theme.palette.accents_2 : theme.palette.accents_8, disabled ? 'not-allow' : 'pointer']]]) + " " + (props && props.className != null && props.className || "slider ".concat(className))
}), /*#__PURE__*/React.createElement(SliderDot, {
disabled: disabled,
ref: dotRef,
isClick: isClick,
left: currentRatio
}, value), showMarkers && /*#__PURE__*/React.createElement(SliderMark, {
max: max,
min: min,
step: step
}), /*#__PURE__*/React.createElement(_JSXStyle, {
id: "3952089332",
dynamic: [disabled ? theme.palette.accents_2 : theme.palette.accents_8, disabled ? 'not-allow' : 'pointer']
}, ".slider.__jsx-style-dynamic-selector{width:100%;height:0.5rem;border-radius:50px;background-color:".concat(disabled ? theme.palette.accents_2 : theme.palette.accents_8, ";position:relative;cursor:").concat(disabled ? 'not-allow' : 'pointer', ";}")));
};
export default withDefaults(Slider, defaultProps);