@drivy/cobalt
Version:
Opinionated design system for Drivy's projects.
102 lines (99 loc) • 4.88 kB
JavaScript
import { jsx, jsxs } from 'react/jsx-runtime';
import cx from 'classnames';
import { PureComponent } from 'react';
import Button from '../Buttons/Button/index.js';
import '../Icon/index.js';
import { withFieldLabelAndHint } from './field.js';
import MinusIcon from '../Icon/__generated__/MinusIcon.js';
import PlusIcon from '../Icon/__generated__/PlusIcon.js';
const AUTO_CHANGE_TIMEOUT_IN_MS = 750;
const AUTO_CHANGE_INTERVAL_IN_MS = 150;
const enforceInRange = (value, min, max) => {
let enforcedValue = value;
if (typeof max !== "undefined") {
enforcedValue = Math.min(enforcedValue, max);
}
if (typeof min !== "undefined") {
enforcedValue = Math.max(enforcedValue, min);
}
return enforcedValue;
};
class Stepper extends PureComponent {
constructor(props) {
super(props);
this.timeout = null;
this.interval = null;
this.onDecrement = () => {
(this.props.min !== null || this.state.value > this.props.min) &&
this.changeValue(parseFloat((this.state.value - this.props.step).toFixed(10)));
};
this.onIncrement = () => {
(this.props.max !== null || this.state.value < this.props.max) &&
this.changeValue(parseFloat((this.state.value + this.props.step).toFixed(10)));
};
this.onPointerDown = (callback) => {
callback();
this.timeout && clearTimeout(this.timeout);
this.timeout = setTimeout(() => {
this.interval && clearInterval(this.interval);
this.interval = setInterval(callback, AUTO_CHANGE_INTERVAL_IN_MS);
}, AUTO_CHANGE_TIMEOUT_IN_MS);
};
this.onPointerUp = () => {
if (this.interval) {
clearInterval(this.interval);
this.interval = null;
}
this.timeout && clearTimeout(this.timeout);
};
this.changeValue = (value) => {
this.setState({
value: enforceInRange(value, this.props.min, this.props.max),
}, () => {
var _a, _b;
(_b = (_a = this.props).onChange) === null || _b === void 0 ? void 0 : _b.call(_a, this.state.value);
});
};
if (props.step < 0)
throw new Error("Incorrect step value. Can't be below zero");
this.onDecrement = this.onDecrement.bind(this);
this.onIncrement = this.onIncrement.bind(this);
this.changeValue = this.changeValue.bind(this);
this.onPointerDown = this.onPointerDown.bind(this);
this.onPointerUp = this.onPointerUp.bind(this);
this.state = {
value: enforceInRange(props.value, props.min, props.max),
};
}
componentDidUpdate(_prevProps, prevState) {
if (prevState.value !== this.state.value) {
this.changeValue(this.state.value);
}
else if (this.props.value !== this.state.value) {
this.changeValue(this.props.value);
}
}
render() {
const { name, status, disabled, min, max, children } = this.props;
return (jsx("div", { className: cx("cobalt-Stepper", {
"cobalt-Stepper--disabled": disabled,
"cobalt-Stepper--success": status === "success",
"cobalt-Stepper--error": status === "error",
}), children: jsxs("div", { className: "cobalt-Stepper__Wrapper", children: [jsx(Button, { className: "cobalt-Stepper__ActionButton", disabled: disabled || this.state.value === min, ...(!disabled && {
onPointerDown: () => this.onPointerDown(this.onDecrement),
onPointerUp: this.onPointerUp,
onPointerLeave: this.onPointerUp,
}), type: "button", "data-label": "stepper-minus", children: jsx(MinusIcon, {}) }), jsxs("div", { className: "cobalt-Stepper__ContentWrapper", children: [children ? children(this.state.value) : this.state.value, jsx("input", { type: "hidden", name: name, value: this.state.value })] }), jsx(Button, { className: "cobalt-Stepper__ActionButton", disabled: disabled || this.state.value === max, ...(!disabled && {
onPointerDown: () => this.onPointerDown(this.onIncrement),
onPointerUp: this.onPointerUp,
onPointerLeave: this.onPointerUp,
}), type: "button", "data-label": "stepper-plus", children: jsx(PlusIcon, {}) })] }) }));
}
}
const wrappedComponent = withFieldLabelAndHint(Stepper);
wrappedComponent.displayName = "Stepper";
const StepperMeta = ({ children }) => {
return jsx("div", { className: "cobalt-Stepper__Meta", children: children });
};
export { wrappedComponent as Stepper, StepperMeta };
//# sourceMappingURL=Stepper.js.map