chakra-ui
Version:
Responsive and accessible React UI components built with React and Emotion
177 lines (160 loc) • 4.68 kB
JavaScript
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
import _extends from "@babel/runtime/helpers/esm/extends";
import React, { forwardRef, useRef, useState } from "react";
import Flex from "../Flex";
import Icon from "../Icon";
import Input from "../Input";
import PseudoBox from "../PseudoBox";
import { useUIMode } from "../ThemeProvider";
import { roundValueToStep } from "../Slider";
var themedProps = {
light: {
borderColor: "inherit",
_active: {
bg: "gray.200"
},
_lastChild: {
roundedBottomRight: 3,
mt: -1,
borderTopWidth: 1
}
},
dark: {
color: "whiteAlpha.800",
borderColor: "whiteAlpha.300",
_lastChild: {
roundedBottomRight: 3,
mt: -1,
borderTopWidth: 1
},
_active: {
bg: "whiteAlpha.300"
}
}
};
var styleProps = function styleProps(_ref) {
var mode = _ref.mode;
return _extends({
borderLeft: "1px",
_firstChild: {
roundedTopRight: 1
},
_disabled: {
opacity: 0.4,
cursor: "not-allowed"
}
}, themedProps[mode]);
};
var Segment = function Segment(_ref2) {
var isDisabled = _ref2.isDisabled,
mode = _ref2.mode,
props = _objectWithoutProperties(_ref2, ["isDisabled", "mode"]);
return React.createElement(PseudoBox, _extends({
display: "flex",
justifyContent: "center",
alignItems: "center",
flex: "1",
cursor: "pointer",
transition: "all 0.3s",
role: "button",
tabindex: "-1",
"aria-disabled": isDisabled
}, styleProps({
mode: mode
}), props));
};
var NumberInput = forwardRef(function (_ref3, ref) {
var size = _ref3.size,
onChange = _ref3.onChange,
min = _ref3.min,
max = _ref3.max,
_ref3$step = _ref3.step,
step = _ref3$step === void 0 ? 1 : _ref3$step,
defaultValue = _ref3.defaultValue,
valueProp = _ref3.value,
isDisabled = _ref3.isDisabled,
wrapperProps = _ref3.wrapperProps,
rest = _objectWithoutProperties(_ref3, ["size", "onChange", "min", "max", "step", "defaultValue", "value", "isDisabled", "wrapperProps"]);
var _useUIMode = useUIMode(),
mode = _useUIMode.mode;
var _useState = useState(defaultValue || 0),
_useState2 = _slicedToArray(_useState, 2),
val = _useState2[0],
setVal = _useState2[1];
var _useRef = useRef(valueProp != null),
isControlled = _useRef.current;
var _value = isControlled ? valueProp : val;
var getNextValue = function getNextValue(nextVal) {
return roundValueToStep(nextVal, step);
};
var handleIncrement = function handleIncrement() {
var nextValue = getNextValue(_value + step);
if (max == null) {
!isControlled && setVal(nextValue);
onChange && onChange(nextValue);
}
if (max != null && max >= nextValue) {
!isControlled && setVal(nextValue);
onChange && onChange(nextValue);
}
};
var handleDecrement = function handleDecrement() {
var nextValue = getNextValue(_value - step);
if (min == null) {
!isControlled && setVal(nextValue);
onChange && onChange(nextValue);
}
if (min != null && min <= nextValue) {
!isControlled && setVal(nextValue);
onChange && onChange(nextValue);
}
};
var handleChange = function handleChange(event) {
var newValue = Number(event.target.value);
!isControlled && setVal(newValue);
onChange && onChange(newValue);
};
var iconSize = size === "sm" ? "11px" : "15px";
return React.createElement(Flex, _extends({
alignItems: "stretch",
position: "relative"
}, wrapperProps), React.createElement(Input, _extends({
size: size,
type: "number",
role: "spinbutton",
"aria-valuemin": min,
"aria-valuemax": max,
"aria-valuenow": _value,
ref: ref,
onChange: handleChange,
value: val,
min: min,
max: max,
step: step,
isDisabled: isDisabled
}, rest)), React.createElement(Flex, {
flexDirection: "column",
"aria-hidden": true,
width: "24px",
m: "1px",
position: "absolute",
right: "0px",
height: "calc(100% - 2px)"
}, React.createElement(Segment, {
onClick: isDisabled ? undefined : handleIncrement,
mode: mode
}, React.createElement(Icon, {
name: "chevron-up",
size: iconSize,
color: "currentColor"
})), React.createElement(Segment, {
onClick: isDisabled ? undefined : handleDecrement,
mode: mode
}, React.createElement(Icon, {
name: "chevron-down",
size: iconSize,
color: "currentColor"
}))));
});
export default NumberInput;