wix-style-react
Version:
wix-style-react
178 lines • 8.68 kB
JavaScript
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