UNPKG

@geneui/components

Version:

The Gene UI components library designed for BI tools

313 lines (309 loc) 12.5 kB
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 };