UNPKG

wix-style-react

Version:
178 lines • 8.68 kB
import React, { Component } from 'react'; import PropTypes from 'prop-types'; import Slide from 'rc-slider'; import { dataHooks } from './constants'; import { generateID } from '../utils/generateId'; import SliderHandle from './SliderHandle'; import Text from '../Text'; import { st, classes } from './Slider.st.css'; import { getRailStyle } from './utils'; const range = ({ min, max, step }) => { const arr = []; for (let i = min; i <= max; i += step) { arr.push(i); } return arr; }; /** * A slider component with multi-range support */ export default class Slider extends Component { constructor() { super(...arguments); this._renderHandle = handleProps => { const { gradientColor, displayTooltip, disabled, marks, dataHook, direction, onFocus, onBlur, enhanceValue, } = this.props; const { index, value, min, max, offset, ref, ariaLabel, reverse, ariaLabelledBy, } = handleProps; let tooltipValue = enhanceValue?.(value) ?? value.toString(); if (this._isCustomMarks()) { if (marks.hasOwnProperty(value)) { tooltipValue = marks[value].toString(); } else { tooltipValue = enhanceValue?.(value); } } return (React.createElement(SliderHandle, { key: index, gradientColor: gradientColor, disabled: disabled, displayTooltip: displayTooltip, tooltipValue: tooltipValue, handleProps: { ref, offset, min, max, value, reverse, ariaLabel, }, index: index, dataHook: dataHook, direction: direction, onBlurCustom: onBlur, onFocusCustom: onFocus, ariaLabelledBy: ariaLabelledBy })); }; this._renderSlider = () => { const { gradientColor, onFocus, onBlur, pushable, allowCross, value, displayMarks, direction, startPoint, dataHook, id, ariaLabelForHandle, ariaLabelledByForHandle, rtl, className, disabled, rangeRef, ...rest } = this.props; return Array.isArray(value) && value.length > 1 ? (React.createElement(Slide.Range, { ...rest, ref: rangeRef, disabled: disabled, vertical: direction === 'vertical', railStyle: getRailStyle({ gradientColor, disabled, direction }), prefixCls: "wsr-slider", handle: this._renderHandle, marks: displayMarks ? this._getMarks() : {}, value: value, pushable: pushable, allowCros: allowCross, reverse: rtl, ariaLabelGroupForHandles: ariaLabelForHandle, ariaLabelledByGroupForHandles: ariaLabelledByForHandle })) : (React.createElement(Slide, { ...rest, disabled: disabled, vertical: direction === 'vertical', railStyle: getRailStyle({ gradientColor, disabled, direction }), prefixCls: "wsr-slider", startPoint: startPoint, handle: this._renderHandle, marks: displayMarks ? this._getMarks() : {}, value: Array.isArray(value) ? value[0] : value, reverse: rtl, ariaLabelForHandle: Array.isArray(ariaLabelForHandle) ? ariaLabelForHandle[0] : ariaLabelForHandle })); }; } _getMarks() { const marksLabels = {}; if (this._isCustomMarks()) { const { marks } = this.props; Object.entries(marks).forEach(([key, value]) => { marksLabels[key] = { label: this._createMarkNode(value, true), }; }); } else { const { min, max, step, startPoint } = this.props; range({ min, max, step }).forEach(entry => { const shouldRenderMarkLabel = entry === min || entry === max || entry === startPoint; marksLabels[entry] = { label: this._createMarkNode(this.props.enhanceValue?.(entry) ?? entry, shouldRenderMarkLabel), }; }); } return marksLabels; } _isCustomMarks() { const { marks } = this.props; return Object.entries(marks).length > 0; } _createMarkNode(value, shouldRenderMarkLabel) { return (React.createElement("div", { className: st(classes.mark, { direction: this.props.direction }) }, React.createElement("div", { className: classes.markLine }), React.createElement("div", { className: classes.markValue }, shouldRenderMarkLabel && (React.createElement(Text, { className: classes.markLabel, dataHook: dataHooks.sliderMarkLabel, weight: "thin", size: "small" }, value))))); } render() { const { dataHook, id, direction, className, gradientColor } = this.props; const hasGradient = !!gradientColor; const horizontal = direction !== 'vertical'; return (React.createElement("div", { className: st(classes.root, { hasGradient, horizontal }, className), id: id, "data-hook": dataHook, "data-direction": direction }, this._renderSlider())); } } Slider.displayName = 'Slider'; Slider.propTypes = { /** Allows sliders handles to cross. */ allowCross: PropTypes.bool, /** Applies a data-hook HTML attribute that can be used in the tests. */ dataHook: PropTypes.string, /** Specifies a CSS class name to be appended to the component’s root element. */ className: PropTypes.string, /** Controls the visibility of the marks. */ displayMarks: PropTypes.bool, /** Controls visibility of slide handle tooltip */ displayTooltip: PropTypes.bool, /** Assigns an unique identifier for the root element. */ id: PropTypes.string, /** Sets the absolute maximum value of sliders range. */ max: PropTypes.number, /** Sets the absolute minimum value of the sliders range. */ min: PropTypes.number, /** Specifies slider marks. The key determines the position, and the value determines what will show. The object structure should be either * ```{ number : number}``` / ```{ number : string }``` * */ marks: PropTypes.object, /** Defines a callback function which will be called when ontouchend or onmouseup is triggered. */ onAfterChange: PropTypes.func, /** Defines a callback function which will be called when ontouchstart or onmousedown is triggered. */ onBeforeChange: PropTypes.func, /** Defines a callback function which is called upon every value change. */ onChange: PropTypes.func.isRequired, /** Adjust component for RTL. */ rtl: PropTypes.bool, /** Provides access to the Range component's ref and its exposed methods. */ rangeRef: PropTypes.object, /** Specifies the interval between range values. */ step: PropTypes.number, /** Push surrounding handles when moving a handle (relevant for multi value sliders only). Number specifies a minimum distance between handles. */ pushable: PropTypes.oneOfType([PropTypes.bool, PropTypes.number]), /** Specifies the selected value. */ value: PropTypes.oneOfType([ PropTypes.arrayOf(PropTypes.number), PropTypes.number, ]), /** Converts value to a string, used to add prefix, suffix, etc */ enhanceValue: PropTypes.func, /** Specifies whether interactions are disabled. */ disabled: PropTypes.bool, /** Specifies the starting value of a track. If undefined, the minimum value of a range is used as a starting point. */ startPoint: PropTypes.number, /** Sets slider direction in either horizontal way or vertical */ direction: PropTypes.oneOf(['vertical', 'horizontal']), /** Set the aria-label attributes for slider handles. */ ariaLabelForHandle: PropTypes.oneOfType([ PropTypes.arrayOf(PropTypes.string), PropTypes.string, ]), /** Sets the onFocus callbak for the slider's handle. * ```javascript * onFocus((handleValue) => ({})) * ``` */ onFocus: PropTypes.func, /** Sets the onBlur callbak for the slider's handle. * ```javascript * onBlur((handleValue) => ({})) * ``` */ onBlur: PropTypes.func, /** Converts slider to a slider with a gradient background. RGB, HEX formats or color names are accepted. * ```javascript * gradientColor="rgb(105, 110, 28)" * gradientColor="#FFAC4B" * gradientColor="pink" * ``` * If color cannot be parsed, fallback color will be applied */ gradientColor: PropTypes.string, }; Slider.defaultProps = { min: 1, max: 20, step: 1, value: 3, allowCross: true, id: generateID(), displayTooltip: true, displayMarks: true, marks: {}, rtl: false, disabled: false, startPoint: undefined, }; //# sourceMappingURL=Slider.js.map