@geneui/components
Version:
The Gene UI components library designed for BI tools
313 lines (309 loc) • 12.5 kB
JavaScript
import React__default, { useRef, useState, useEffect, useMemo, useCallback } from 'react';
import { c as classnames } from '../index-031ff73c.js';
import PropTypes from 'prop-types';
import { n as noop, s as stopEvent } from '../index-a0e4e333.js';
import useKeyDown from '../hooks/useKeyDown.js';
import '../configs-00612ce0.js';
import Button from '../Button/index.js';
import Label from '../Label/index.js';
import SkeletonLoader from '../SkeletonLoader/index.js';
import { T as Tooltip } from '../index-6d7e99cd.js';
import ExtendedInput from '../ExtendedInput/index.js';
import { s as styleInject } from '../style-inject.es-746bb8ed.js';
import '../dateValidation-67caec66.js';
import '../_commonjsHelpers-24198af3.js';
import 'react-dom';
import '../tslib.es6-f211516f.js';
import '../Icon/index.js';
import '../_rollupPluginBabelHelpers-e8fb2e5c.js';
import '../hooks/useDeviceType.js';
import '../hooks/useWindowSize.js';
import '../hooks/useDebounce.js';
import '../GeneUIProvider/index.js';
import '../useEllipsisDetection-4d997d5d.js';
import '../SuggestionList/index.js';
import '../hooks/useClickOutside.js';
import '../config-1053d64d.js';
import '../Scrollbar/index.js';
import '../callAfterDelay-7272faca.js';
var css_248z = "[data-gene-ui-version=\"2.16.5\"] .counter{width:100%}[data-gene-ui-version=\"2.16.5\"] .counter.s-small{--height:2.4rem;--width:var(--height);min-width:8rem}[data-gene-ui-version=\"2.16.5\"] .counter.s-medium{--height:3.6rem;--width:var(--height);min-width:12rem}[data-gene-ui-version=\"2.16.5\"] .counter.s-big{--height:4.2rem;--width:var(--height);min-width:14rem}[data-gene-ui-version=\"2.16.5\"] .counter.r-round .react-loading-skeleton{border-radius:4.2rem}[data-gene-ui-version=\"2.16.5\"] .counter.r-smooth .react-loading-skeleton{border-radius:.4rem}[data-gene-ui-version=\"2.16.5\"] .counter__label{color:rgba(var(--background-sc-rgb),.75);font-size:1.4rem;font-weight:600;margin-bottom:.8rem;opacity:.5}[data-gene-ui-version=\"2.16.5\"] .counter__wrapper{display:flex;gap:.4rem;height:var(--height)}[data-gene-ui-version=\"2.16.5\"] .counter__input{opacity:1!important}[data-gene-ui-version=\"2.16.5\"] .counter__input-holder{display:flex;min-width:var(---width);overflow:hidden;width:100%}[data-gene-ui-version=\"2.16.5\"] .counter__input-holder .react-loading-skeleton{height:var(--height)!important}[data-gene-ui-version=\"2.16.5\"] .counter__input .input-structure{padding:0}[data-gene-ui-version=\"2.16.5\"] .counter__input .input-element{justify-content:center;max-height:var(--height);min-height:var(--height);text-align:center}[data-gene-ui-version=\"2.16.5\"] .counter__input .input-element:disabled{color:rgba(var(--background-sc-rgb),.5)}[data-gene-ui-version=\"2.16.5\"] .counter__button{height:100%;min-height:100%;min-width:var(--width);width:var(--width)}[data-gene-ui-version=\"2.16.5\"] .counter__button .btn{max-height:100%;max-width:100%;min-height:100%;min-width:100%}[data-gene-ui-version=\"2.16.5\"] .counter__button .skeleton-holder .react-loading-skeleton{height:var(--height)!important;width:var(--width)}";
styleInject(css_248z);
const keyDownKeys = {
arrowUp: 'ArrowUp',
arrowDown: 'ArrowDown'
};
const inputRadiusMap = {
round: 'full-radius',
smooth: 'smooth-radius'
};
function Counter(_ref) {
let {
minusTooltipText,
plusTooltipText,
inputReadOnly,
defaultValue,
cornerRadius,
isLoading,
className,
minValue,
maxValue,
readOnly,
disabled,
onChange,
label,
value,
width,
size,
step
} = _ref;
const ref = useRef();
const inputRef = useRef();
const [showInputTooltip, setShowInputTooltip] = useState(false);
const [isTruncated, setIsTruncated] = useState(false);
const [data, setData] = useState(defaultValue || 0);
const [counterStep, setCounterStep] = useState(step);
useEffect(() => setCounterStep(step), [step]);
const isMinMaxWrong = useMemo(() => minValue >= maxValue, [minValue, maxValue]);
const isControlled = useMemo(() => value === 0 || !!value, [value]);
const modifiedSize = useMemo(() => typeof width === 'number' ? "".concat(width, "px") : width, [width]);
const isDisableMinus = useMemo(() => +data === minValue, [minValue, data]);
const isDisablePlus = useMemo(() => +data === maxValue, [maxValue, data]);
const isMinValue = useMemo(() => minValue !== undefined, [minValue]);
const isMaxValue = useMemo(() => maxValue !== undefined, [maxValue]);
useEffect(() => {
if (typeof defaultValue === 'number' && defaultValue <= maxValue && defaultValue >= minValue) {
return setData(defaultValue);
}
if (typeof minValue === 'number' && minValue > defaultValue) {
return setData(minValue);
}
}, [minValue, defaultValue, maxValue]);
useEffect(() => {
isControlled && setData(value);
}, [value]);
const setNewValue = useCallback(val => {
!isControlled && setData(eventState => (+eventState + +val).toString());
onChange((+data + +val).toString());
}, [isControlled, data]);
const setValueToMin = useCallback(() => {
!isControlled && setData(minValue === null || minValue === void 0 ? void 0 : minValue.toString());
onChange(minValue === null || minValue === void 0 ? void 0 : minValue.toString());
}, [isControlled, minValue]);
const setValueToMax = useCallback(() => {
!isControlled && setData(maxValue === null || maxValue === void 0 ? void 0 : maxValue.toString());
onChange(maxValue === null || maxValue === void 0 ? void 0 : maxValue.toString());
}, [isControlled, maxValue]);
const handleChange = useCallback(val => {
if (isMinValue && isMaxValue) {
if (+data <= maxValue && +data >= minValue && +val + +data <= maxValue && +val + +data >= minValue || val === '-') {
setNewValue(val);
} else if (+val + +data > maxValue) {
setValueToMax();
} else if (+val + +data < minValue) {
setValueToMin();
}
} else if (isMaxValue && +data <= maxValue || val === '-') {
if (+val + +data <= maxValue) {
setNewValue(val);
} else {
setValueToMax();
}
} else if (isMinValue && +data >= minValue || val === '-') {
if (+val + +data >= minValue) {
setNewValue(val);
} else {
setValueToMin();
}
} else {
setNewValue(val);
}
}, [data, isControlled]);
const setNewInputValue = useCallback(value => {
!isControlled && setData(value.trim());
!isNaN(+value) && onChange(value);
}, [isControlled]);
const handleInputChange = useCallback(_ref2 => {
let {
target: {
value
}
} = _ref2;
if (isMinValue && isMaxValue) {
if (+value <= maxValue && +value >= minValue || value === '-') {
setNewInputValue(value);
}
} else if (isMaxValue) {
if (+value <= maxValue) {
setNewInputValue(value);
} else if (value === '-') {
setNewInputValue(value);
}
} else if (isMinValue) {
if (+value >= minValue) {
setNewInputValue(value);
} else if (value === '-') {
setNewInputValue(value);
}
} else {
setNewInputValue(value);
}
}, [maxValue, minValue]);
useKeyDown(e => {
stopEvent(e, true);
if (e.key === keyDownKeys.arrowUp && !isDisablePlus) {
handleChange(counterStep);
}
if (e.key === keyDownKeys.arrowDown && !isDisableMinus) {
handleChange(-counterStep);
}
}, [handleChange], ref, [keyDownKeys.arrowUp, keyDownKeys.arrowDown]);
useEffect(() => {
var _inputRef$current, _inputRef$current2;
if (((_inputRef$current = inputRef.current) === null || _inputRef$current === void 0 ? void 0 : _inputRef$current.scrollWidth) > ((_inputRef$current2 = inputRef.current) === null || _inputRef$current2 === void 0 ? void 0 : _inputRef$current2.offsetWidth)) {
!isTruncated && setIsTruncated(true);
} else {
isTruncated && setIsTruncated(false);
}
}, [data]);
return /*#__PURE__*/React__default.createElement("div", {
ref: ref,
style: {
maxWidth: modifiedSize
},
onMouseOver: () => isTruncated && setShowInputTooltip(true),
onMouseLeave: () => isTruncated && setShowInputTooltip(false),
className: classnames('counter', className, "s-".concat(size), "r-".concat(cornerRadius))
}, label && /*#__PURE__*/React__default.createElement(Tooltip, {
title: label
}, /*#__PURE__*/React__default.createElement(Label, {
className: "counter__label ellipsis-text",
size: "bodySmall"
}, label)), /*#__PURE__*/React__default.createElement("div", {
className: "counter__wrapper"
}, !readOnly && /*#__PURE__*/React__default.createElement(Tooltip, {
title: isDisableMinus && !isLoading ? minusTooltipText : ''
}, /*#__PURE__*/React__default.createElement("div", {
className: "counter__button counter__button-minus"
}, isLoading ? /*#__PURE__*/React__default.createElement(SkeletonLoader, {
isBusy: isLoading
}) : /*#__PURE__*/React__default.createElement(Button, {
icon: isLoading ? 'bc-icon-loader' : 'bc-icon-minus',
disabled: isMinMaxWrong || isDisableMinus || disabled,
cornerRadius: cornerRadius,
onClick: () => handleChange(-counterStep)
}))), /*#__PURE__*/React__default.createElement(Tooltip, {
alwaysShow: showInputTooltip,
title: isTruncated ? data : ''
}, /*#__PURE__*/React__default.createElement("div", {
className: "counter__input-holder"
}, isLoading ? /*#__PURE__*/React__default.createElement(SkeletonLoader, {
isBusy: isLoading
}) : /*#__PURE__*/React__default.createElement(ExtendedInput, {
ref: inputRef,
className: "counter__input",
disabled: isMinMaxWrong || disabled || isLoading,
cornerRadius: inputRadiusMap[cornerRadius],
onChange: handleInputChange,
showNumberIcon: false,
readOnly: readOnly || inputReadOnly,
type: "number",
value: data
}))), !readOnly && /*#__PURE__*/React__default.createElement(Tooltip, {
title: isDisablePlus && !isLoading ? plusTooltipText : ''
}, /*#__PURE__*/React__default.createElement("div", {
className: "counter__button counter__button-plus"
}, isLoading ? /*#__PURE__*/React__default.createElement(SkeletonLoader, {
isBusy: isLoading
}) : /*#__PURE__*/React__default.createElement(Button, {
icon: isLoading ? 'bc-icon-loader' : 'bc-icon-plus',
disabled: isMinMaxWrong || isDisablePlus || disabled,
cornerRadius: cornerRadius,
onClick: () => handleChange(counterStep)
})))));
}
const CounterConfig = {
size: ['small', 'medium', 'big'],
cornerRadius: ['round', 'smooth']
};
Counter.propTypes = {
/**
* Additional className
*/
className: PropTypes.string,
/**
* counter will become disabled when set to "true"
*/
disabled: PropTypes.bool,
/**
* counter input will become readonly when set to "true"
*/
inputReadOnly: PropTypes.bool,
/**
* Label for 'counter'.
*/
label: PropTypes.string,
/**
* onChange function which returns callBack if there is a change
*/
onChange: PropTypes.func,
/**
* Use this prop to control counter state. Note that when you specify this prop, the counter will not functionate itself
*/
value: PropTypes.number,
/**
* This prop will only applied once as defaultState for "value" when counter mounts.
* Note that specifying this prop is not mean controlling it.
*/
defaultValue: PropTypes.number,
/**
* Is loading state.
*/
isLoading: PropTypes.bool,
/**
* counter size, if the set value is number default use px
*/
width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
/**
* counter size
*/
size: PropTypes.oneOf(CounterConfig.size),
/**
* counter corner radius
*/
cornerRadius: PropTypes.oneOf(CounterConfig.cornerRadius),
/**
* minus tooltip text
*/
minusTooltipText: PropTypes.string,
/**
* plus tooltip text
*/
plusTooltipText: PropTypes.string,
/**
* Counter minimum value
*/
minValue: PropTypes.number,
/**
* Counter maximum value
*/
maxValue: PropTypes.number,
/**
* Counter step value
*/
step: PropTypes.number
};
Counter.defaultProps = {
cornerRadius: CounterConfig.cornerRadius[0],
size: CounterConfig.size[1],
minusTooltipText: '',
inputReadOnly: false,
plusTooltipText: '',
isLoading: false,
disabled: false,
readOnly: false,
onChange: noop,
width: '100px',
label: '',
step: 1
};
export { Counter as default };