UNPKG

@massds/mayflower-react

Version:

React versions of Mayflower design system UI components

351 lines (350 loc) 14.6 kB
"use strict"; exports.__esModule = true; exports["default"] = void 0; var _react = _interopRequireDefault(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _classnames = _interopRequireDefault(require("classnames")); var _numbro = _interopRequireDefault(require("numbro")); var _es = require("react-compound-slider/es"); var _context = require("../Input/context.js"); var _utility = require("../Input/utility.js"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; } function _inheritsLoose(t, o) { t.prototype = Object.create(o.prototype), t.prototype.constructor = t, _setPrototypeOf(t, o); } function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { return t.__proto__ = e, t; }, _setPrototypeOf(t, e); } function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } /** * CompoundSlider module. * @module @massds/mayflower-react/CompoundSlider */ var Handle = function Handle(props) { var _props$handle = props.handle, id = _props$handle.id, value = _props$handle.value, percent = _props$handle.percent, getHandleProps = props.getHandleProps, axis = props.axis, min = props.min, max = props.max, step = props.step, displayValueFormat = props.displayValueFormat, disabled = props.disabled; var decimalPlaces = (0, _utility.countDecimals)(step); var roundedValue = Number.isInteger(step) ? value : Number(Number.parseFloat(value).toFixed(decimalPlaces)); var divProps = _extends({ 'aria-valuemin': min, 'aria-valuemax': max, 'aria-valuenow': roundedValue, disabled: disabled, role: 'slider', onClick: function onClick(e) { e.preventDefault(); } }, getHandleProps(id)); if (axis === 'x') { divProps.style = { left: percent + "%" }; } else if (axis === 'y') { divProps.style = { top: percent + "%" }; } return /*#__PURE__*/_react["default"].createElement("button", _extends({ type: "button", className: "ma__slider-handle" }, divProps), displayValueFormat && /*#__PURE__*/_react["default"].createElement("div", { className: "ma__slider-handle-value" }, displayValueFormat === 'percentage' ? (0, _numbro["default"])(value).format({ output: 'percent', mantissa: 0 }) : roundedValue)); }; Handle.propTypes = process.env.NODE_ENV !== "production" ? { handle: { id: _propTypes["default"].string, value: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].number]), percent: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].number]) }, getHandleProps: _propTypes["default"].func, axis: _propTypes["default"].string, min: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].number]), max: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].number]), step: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].number]), displayValueFormat: _propTypes["default"].string, disabled: _propTypes["default"].bool } : {}; var Track = function Track(props) { var source = props.source, target = props.target, getTrackProps = props.getTrackProps, axis = props.axis; var divProps = _extends({}, getTrackProps()); if (axis === 'x') { divProps.style = { left: source.percent + "%", width: target.percent - source.percent + "%" }; } else if (axis === 'y') { divProps.style = { top: source.percent + "%", height: target.percent - source.percent + "%" }; } return /*#__PURE__*/_react["default"].createElement("div", _extends({ className: "ma__slider-track" }, divProps)); }; Track.propTypes = process.env.NODE_ENV !== "production" ? { source: { percent: _propTypes["default"].string }, target: { percent: _propTypes["default"].string }, getTrackProps: _propTypes["default"].func, axis: _propTypes["default"].string } : {}; var Tick = function Tick(props) { var tick = props.tick, count = props.count, axis = props.axis, id = props.id; var top = {}; var bottom = {}; if (axis === 'x') { top.style = { left: tick.percent + "%" }; bottom.style = { marginLeft: -(100 / count) / 2 + "%", width: 100 / count + "%", left: tick.percent + "%" }; } else if (axis === 'y') { top.style = { top: tick.percent + "%" }; bottom.style = { top: tick.percent + "%" }; } return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement("div", _extends({ className: "ma__slider-tick ma__slider-tick--top" }, top)), /*#__PURE__*/_react["default"].createElement("div", _extends({ className: "ma__slider-tick ma__slider-tick--bottom" }, bottom), /*#__PURE__*/_react["default"].createElement("label", { htmlFor: id }, tick.value))); }; Tick.propTypes = process.env.NODE_ENV !== "production" ? { tick: { percent: _propTypes["default"].string, value: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].number]) }, count: _propTypes["default"].number, getTrackProps: _propTypes["default"].func, id: _propTypes["default"].string, axis: _propTypes["default"].string } : {}; var CompoundSlider = /*#__PURE__*/function (_React$Component) { function CompoundSlider() { return _React$Component.apply(this, arguments) || this; } _inheritsLoose(CompoundSlider, _React$Component); var _proto = CompoundSlider.prototype; _proto.render = function render() { var _this = this; return /*#__PURE__*/_react["default"].createElement(_context.InputContext.Consumer, null, function (context) { var _this$props = _this.props, min = _this$props.min, max = _this$props.max, step = _this$props.step, disabled = _this$props.disabled, domain = _this$props.domain, onChange = _this$props.onChange, onUpdate = _this$props.onUpdate; var decimalPlaces = (0, _utility.countDecimals)(step); var handleChange = function handleChange(values) { var value = Number.isInteger(step) ? values[0] : Number(Number.parseFloat(values[0]).toFixed(decimalPlaces)); context.updateState({ value: value }, function () { if (typeof onChange === 'function') { onChange(value, _this.props.id); } }); }; var handleUpdate = function handleUpdate(values) { var value = Number.isInteger(step) ? values[0] : Number(Number.parseFloat(values[0]).toFixed(decimalPlaces)); context.updateState({ value: value }, function () { if (typeof onUpdate === 'function') { onUpdate(value, _this.props.id); } }); }; var domainCheck = function domainCheck(valToCheck) { var minCheck = Number(min); var maxCheck = Number(max); if (Number.isNaN(valToCheck)) { return Number.isInteger(step) ? minCheck : Number(Number.parseFloat(minCheck).toFixed(decimalPlaces)); } var returnValue = valToCheck; var domainMin = domain[0], domainMax = domain[1]; // If the min/max passed falls outside of the domain, set it to the respective domain min/max. if (Number.isNaN(minCheck) || Math.abs(minCheck - domainMax) > Math.abs(domainMin - domainMax)) { minCheck = domainMin; } if (Number.isNaN(maxCheck) || Math.abs(maxCheck - domainMin) > Math.abs(domainMin - domainMax)) { maxCheck = domainMax; } // Ensure the value is always between the min or max values, if any. if (valToCheck < minCheck) { returnValue = minCheck; } if (valToCheck > maxCheck) { returnValue = maxCheck; } return Number.isInteger(step) ? returnValue : Number(Number.parseFloat(returnValue).toFixed(decimalPlaces)); }; // Anything returned by mode when set to a function will become the value. // This can be used for min/max validation. // Next and current values are not numbers, but arrays of objects. var handleMode = function handleMode(current, next) { var nextValue = next[0].val; var checkValue = Number.isInteger(step) ? nextValue : Number(Number.parseFloat(nextValue).toFixed(decimalPlaces)); if (checkValue === domainCheck(nextValue)) { return next; } return current; }; var defaultValue = domainCheck(Number(context.getValue())); var sliderProps = { domain: domain, step: step, vertical: !(_this.props.axis === 'x'), onChange: handleChange, values: [defaultValue], mode: handleMode, disabled: disabled }; if (onUpdate) { sliderProps.onUpdate = handleUpdate; } var wrapperClasses = (0, _classnames["default"])({ 'ma__input-slider': true, 'ma__input-slider--disabled': disabled, 'ma__input-slider-x': _this.props.axis === 'x', 'ma__input-slider-y': _this.props.axis === 'y' }); return /*#__PURE__*/_react["default"].createElement("div", { id: _this.props.id, className: wrapperClasses }, /*#__PURE__*/_react["default"].createElement(_es.Slider, _extends({ className: "ma__slider" }, sliderProps), /*#__PURE__*/_react["default"].createElement(_es.Rail, null, function (_ref) { var getRailProps = _ref.getRailProps; return /*#__PURE__*/_react["default"].createElement("div", _extends({ className: "ma__slider-rail" }, getRailProps())); }), /*#__PURE__*/_react["default"].createElement(_es.Handles, null, function (_ref2) { var handles = _ref2.handles, activeHandleID = _ref2.activeHandleID, getHandleProps = _ref2.getHandleProps; return /*#__PURE__*/_react["default"].createElement("div", { className: "slider-handles" }, handles.map(function (handle) { return /*#__PURE__*/_react["default"].createElement(Handle, { key: handle.id, handle: handle, getHandleProps: getHandleProps, isActive: handle.id === activeHandleID, axis: _this.props.axis, min: min, max: max, step: step, displayValueFormat: _this.props.displayValueFormat, disabled: disabled }); })); }), /*#__PURE__*/_react["default"].createElement(_es.Tracks, { right: false }, function (_ref3) { var tracks = _ref3.tracks, getTrackProps = _ref3.getTrackProps; return /*#__PURE__*/_react["default"].createElement("div", { className: "slider-tracks" }, tracks.map(function (_ref4) { var id = _ref4.id, source = _ref4.source, target = _ref4.target; return /*#__PURE__*/_react["default"].createElement(Track, { key: id, source: source, target: target, getTrackProps: getTrackProps, axis: _this.props.axis }); })); }), /*#__PURE__*/_react["default"].createElement(_es.Ticks, { values: Array.from(_this.props.ticks.keys()) }, function (_ref5) { var ticks = _ref5.ticks; var ticksLength = ticks.length; // Placing this check here because Slider can't handle null children but Ticks can. if (ticksLength > 0) { return /*#__PURE__*/_react["default"].createElement("div", { className: "slider-ticks" }, ticks.map(function (oldTick) { var tick = _extends({}, oldTick, { value: _this.props.ticks.get(oldTick.value) }); var tickProps = { key: "CompoundSlider.tick." + tick.value, count: ticksLength, tick: tick, axis: _this.props.axis, id: _this.props.id }; return /*#__PURE__*/_react["default"].createElement(Tick, tickProps); })); } return null; }))); }); }; return CompoundSlider; }(_react["default"].Component); CompoundSlider.propTypes = process.env.NODE_ENV !== "production" ? { /** The unique ID for the input field */ id: _propTypes["default"].string.isRequired, /** Custom update function, triggered with the values on drag (caution: high-volume updates when dragging). Only if a function is passed to onUpdate will form context get updated on drag. */ onUpdate: _propTypes["default"].func, /** Custom on change function, triggered when the value of the slider has changed. This will recieve changes at the end of a slide as well as changes from clicks on rails and tracks. */ onChange: _propTypes["default"].func, /** Default input text value */ defaultValue: _propTypes["default"].string, /** Max value for the field. */ max: _propTypes["default"].number.isRequired, /** Min value for the field. */ min: _propTypes["default"].number.isRequired, /** This controls how much sliding the handle increments/decrements the value of the slider. */ step: _propTypes["default"].number, /** A Map object where each entry is a key (number inclusively between min and max) and value (label to display at the key) pair for displaying tick marks. */ ticks: _propTypes["default"].instanceOf(Map), /** The direction for the slider, where x is horizontal and y is vertical. */ axis: _propTypes["default"].oneOf(['x', 'y']), /** Disables the slider if true. */ disabled: _propTypes["default"].bool, /** The range of numbers, inclusively, for the slider to fall between. First number is the min and second number is the max. */ domain: _propTypes["default"].arrayOf(_propTypes["default"].number), /** Display the value of the slider based. If null, don't display. If equals percentage, format the value in percentage. */ displayValueFormat: _propTypes["default"].oneOf(['percentage', 'value', null]) } : {}; CompoundSlider.defaultProps = { ticks: new Map(), domain: [0, 1] }; var _default = exports["default"] = CompoundSlider; module.exports = exports.default;