@yamada-ui/react
Version:
React UI components of the Yamada, by the Yamada, for the Yamada built with React and Emotion
114 lines (110 loc) • 3.16 kB
JavaScript
"use client";
import { useCallbackRef } from "../../utils/ref.js";
import { utils_exports } from "../../utils/index.js";
import { useCallback, useState } from "react";
//#region src/hooks/use-counter/index.ts
const parse = (value) => parseFloat(value.toString().replace(/[^\w.-]+/g, ""));
const getCountDecimal = (value, step) => Math.max((0, utils_exports.countDecimal)(step), (0, utils_exports.countDecimal)(value));
const casting = (value, step, precision) => {
value = parse(value);
return !Number.isNaN(value) ? (0, utils_exports.toPrecision)(value, precision ?? getCountDecimal(value, step)) : void 0;
};
/**
* `useCounter` is a custom hook that returns the current counter value.
*
* @see https://yamada-ui.com/docs/hooks/use-counter
*/
const useCounter = ({ keepWithinRange = true, max: maxValue = Number.MAX_SAFE_INTEGER, min: minValue = Number.MIN_SAFE_INTEGER, step: stepProp = 1,...props } = {}) => {
const onChange = useCallbackRef(props.onChange);
const [defaultValue, setValue] = useState(() => {
if (props.defaultValue == null) return "";
return casting(props.defaultValue, stepProp, props.precision) ?? "";
});
const isControlled = typeof props.value !== "undefined";
const value = isControlled ? props.value : defaultValue;
const countDecimal$1 = getCountDecimal(parse(value), stepProp);
const precision = props.precision ?? countDecimal$1;
const update = useCallback((next) => {
if (next === value) return;
if (!isControlled) setValue(next.toString());
onChange(next.toString(), parse(next));
}, [
onChange,
isControlled,
value
]);
const clamp = useCallback((value$1) => {
let nextValue = value$1;
if (keepWithinRange) nextValue = (0, utils_exports.clampNumber)(nextValue, minValue, maxValue);
return (0, utils_exports.toPrecision)(nextValue, precision);
}, [
precision,
keepWithinRange,
maxValue,
minValue
]);
const increment = useCallback((step = stepProp) => {
let next;
if (value === "") next = parse(step);
else next = parse(value) + step;
next = clamp(next);
update(next);
}, [
clamp,
stepProp,
update,
value
]);
const decrement = useCallback((step = stepProp) => {
let next;
if (value === "") next = parse(-step);
else next = parse(value) - step;
next = clamp(next);
update(next);
}, [
clamp,
stepProp,
update,
value
]);
const reset = useCallback(() => {
let next;
if (props.defaultValue == null) next = "";
else next = casting(props.defaultValue, stepProp, props.precision) ?? minValue;
update(next);
}, [
props.defaultValue,
props.precision,
stepProp,
update,
minValue
]);
const cast = useCallback((value$1) => {
update(casting(value$1, stepProp, precision) ?? minValue);
}, [
precision,
stepProp,
update,
minValue
]);
const valueAsNumber = parse(value);
return {
cast,
clamp,
decrement,
increment,
max: valueAsNumber === maxValue,
min: valueAsNumber === minValue,
out: valueAsNumber < minValue || maxValue < valueAsNumber,
precision,
reset,
setValue,
step: stepProp,
update,
value,
valueAsNumber
};
};
//#endregion
export { useCounter };
//# sourceMappingURL=index.js.map