@yamada-ui/react
Version:
React UI components of the Yamada, by the Yamada, for the Yamada built with React and Emotion
1 lines • 6.94 kB
Source Map (JSON)
{"version":3,"file":"index.cjs","names":["useCallbackRef","countDecimal","value","next: number | string"],"sources":["../../../../src/hooks/use-counter/index.ts"],"sourcesContent":["\"use client\"\n\nimport { useCallback, useState } from \"react\"\nimport {\n clampNumber,\n countDecimal,\n toPrecision,\n useCallbackRef,\n} from \"../../utils\"\n\nconst parse = (value: number | string): number =>\n parseFloat(value.toString().replace(/[^\\w.-]+/g, \"\"))\n\nconst getCountDecimal = (value: number, step: number): number =>\n Math.max(countDecimal(step), countDecimal(value))\n\nconst casting = (\n value: number | string,\n step: number,\n precision?: number,\n): string | undefined => {\n value = parse(value)\n\n return !Number.isNaN(value)\n ? toPrecision(value, precision ?? getCountDecimal(value, step))\n : undefined\n}\n\nexport interface UseCounterProps {\n /**\n * The initial value of the counter.\n * Should be less than `max` and greater than `min`.\n */\n defaultValue?: number | string\n /**\n * This controls the value update behavior in general.\n *\n * - If `true` and you use the stepper or up/down arrow keys,\n * the value will not exceed the `max` or go lower than `min`.\n *\n * - If `false`, the value will be allowed to go out of range.\n *\n * @default true\n */\n keepWithinRange?: boolean\n /**\n * The maximum value of the counter\n *\n * @default Number.MAX_SAFE_INTEGER\n */\n max?: number\n /**\n * The minimum value of the counter\n *\n * @default Number.MIN_SAFE_INTEGER\n */\n min?: number\n /**\n * The number of decimal points used to round the value.\n */\n precision?: number\n /**\n * The step used to increment or decrement the value.\n *\n * @default 1\n */\n step?: number\n /**\n * The value of the counter.\n * Should be less than `max` and greater than `min`.\n */\n value?: number | string\n /**\n * The callback fired when the value changes.\n */\n onChange?: (valueAsString: string, valueAsNumber: number) => void\n}\n\n/**\n * `useCounter` is a custom hook that returns the current counter value.\n *\n * @see https://yamada-ui.com/docs/hooks/use-counter\n */\nexport const useCounter = ({\n keepWithinRange = true,\n max: maxValue = Number.MAX_SAFE_INTEGER,\n min: minValue = Number.MIN_SAFE_INTEGER,\n step: stepProp = 1,\n ...props\n}: UseCounterProps = {}) => {\n const onChange = useCallbackRef(props.onChange)\n\n const [defaultValue, setValue] = useState<number | string>(() => {\n if (props.defaultValue == null) return \"\"\n\n return casting(props.defaultValue, stepProp, props.precision) ?? \"\"\n })\n\n const isControlled = typeof props.value !== \"undefined\"\n const value = isControlled ? (props.value as number | string) : defaultValue\n\n const countDecimal = getCountDecimal(parse(value), stepProp)\n\n const precision = props.precision ?? countDecimal\n\n const update = useCallback(\n (next: number | string) => {\n if (next === value) return\n\n if (!isControlled) setValue(next.toString())\n\n onChange(next.toString(), parse(next))\n },\n [onChange, isControlled, value],\n )\n\n const clamp = useCallback(\n (value: number) => {\n let nextValue = value\n\n if (keepWithinRange)\n nextValue = clampNumber(nextValue, minValue, maxValue)\n\n return toPrecision(nextValue, precision)\n },\n [precision, keepWithinRange, maxValue, minValue],\n )\n\n const increment = useCallback(\n (step = stepProp) => {\n let next: number | string\n\n if (value === \"\") {\n next = parse(step)\n } else {\n next = parse(value) + step\n }\n\n next = clamp(next as number)\n\n update(next)\n },\n [clamp, stepProp, update, value],\n )\n\n const decrement = useCallback(\n (step = stepProp) => {\n let next: number | string\n\n if (value === \"\") {\n next = parse(-step)\n } else {\n next = parse(value) - step\n }\n\n next = clamp(next as number)\n\n update(next)\n },\n [clamp, stepProp, update, value],\n )\n\n const reset = useCallback(() => {\n let next: number | string\n\n if (props.defaultValue == null) {\n next = \"\"\n } else {\n next = casting(props.defaultValue, stepProp, props.precision) ?? minValue\n }\n\n update(next)\n }, [props.defaultValue, props.precision, stepProp, update, minValue])\n\n const cast = useCallback(\n (value: number | string) => {\n const nextValue = casting(value, stepProp, precision) ?? minValue\n\n update(nextValue)\n },\n [precision, stepProp, update, minValue],\n )\n\n const valueAsNumber = parse(value)\n\n const out = valueAsNumber < minValue || maxValue < valueAsNumber\n const max = valueAsNumber === maxValue\n const min = valueAsNumber === minValue\n\n return {\n cast,\n clamp,\n decrement,\n increment,\n max,\n min,\n out,\n precision,\n reset,\n setValue,\n step: stepProp,\n update,\n value,\n valueAsNumber,\n }\n}\n\nexport type UseCounterReturn = ReturnType<typeof useCounter>\n"],"mappings":";;;;;;;;;;AAUA,MAAM,SAAS,UACb,WAAW,MAAM,UAAU,CAAC,QAAQ,aAAa,GAAG,CAAC;AAEvD,MAAM,mBAAmB,OAAe,SACtC,KAAK,wDAAiB,KAAK,sDAAe,MAAM,CAAC;AAEnD,MAAM,WACJ,OACA,MACA,cACuB;AACvB,SAAQ,MAAM,MAAM;AAEpB,QAAO,CAAC,OAAO,MAAM,MAAM,sDACX,OAAO,aAAa,gBAAgB,OAAO,KAAK,CAAC,GAC7D;;;;;;;AA0DN,MAAa,cAAc,EACzB,kBAAkB,MAClB,KAAK,WAAW,OAAO,kBACvB,KAAK,WAAW,OAAO,kBACvB,MAAM,WAAW,EACjB,GAAG,UACgB,EAAE,KAAK;CAC1B,MAAM,WAAWA,2BAAe,MAAM,SAAS;CAE/C,MAAM,CAAC,cAAc,sCAA4C;AAC/D,MAAI,MAAM,gBAAgB,KAAM,QAAO;AAEvC,SAAO,QAAQ,MAAM,cAAc,UAAU,MAAM,UAAU,IAAI;GACjE;CAEF,MAAM,eAAe,OAAO,MAAM,UAAU;CAC5C,MAAM,QAAQ,eAAgB,MAAM,QAA4B;CAEhE,MAAMC,iBAAe,gBAAgB,MAAM,MAAM,EAAE,SAAS;CAE5D,MAAM,YAAY,MAAM,aAAaA;CAErC,MAAM,iCACH,SAA0B;AACzB,MAAI,SAAS,MAAO;AAEpB,MAAI,CAAC,aAAc,UAAS,KAAK,UAAU,CAAC;AAE5C,WAAS,KAAK,UAAU,EAAE,MAAM,KAAK,CAAC;IAExC;EAAC;EAAU;EAAc;EAAM,CAChC;CAED,MAAM,gCACH,YAAkB;EACjB,IAAI,YAAYC;AAEhB,MAAI,gBACF,gEAAwB,WAAW,UAAU,SAAS;AAExD,4DAAmB,WAAW,UAAU;IAE1C;EAAC;EAAW;EAAiB;EAAU;EAAS,CACjD;CAED,MAAM,oCACH,OAAO,aAAa;EACnB,IAAIC;AAEJ,MAAI,UAAU,GACZ,QAAO,MAAM,KAAK;MAElB,QAAO,MAAM,MAAM,GAAG;AAGxB,SAAO,MAAM,KAAe;AAE5B,SAAO,KAAK;IAEd;EAAC;EAAO;EAAU;EAAQ;EAAM,CACjC;CAED,MAAM,oCACH,OAAO,aAAa;EACnB,IAAIA;AAEJ,MAAI,UAAU,GACZ,QAAO,MAAM,CAAC,KAAK;MAEnB,QAAO,MAAM,MAAM,GAAG;AAGxB,SAAO,MAAM,KAAe;AAE5B,SAAO,KAAK;IAEd;EAAC;EAAO;EAAU;EAAQ;EAAM,CACjC;CAED,MAAM,qCAA0B;EAC9B,IAAIA;AAEJ,MAAI,MAAM,gBAAgB,KACxB,QAAO;MAEP,QAAO,QAAQ,MAAM,cAAc,UAAU,MAAM,UAAU,IAAI;AAGnE,SAAO,KAAK;IACX;EAAC,MAAM;EAAc,MAAM;EAAW;EAAU;EAAQ;EAAS,CAAC;CAErE,MAAM,+BACH,YAA2B;AAG1B,SAFkB,QAAQD,SAAO,UAAU,UAAU,IAAI,SAExC;IAEnB;EAAC;EAAW;EAAU;EAAQ;EAAS,CACxC;CAED,MAAM,gBAAgB,MAAM,MAAM;AAMlC,QAAO;EACL;EACA;EACA;EACA;EACA,KARU,kBAAkB;EAS5B,KARU,kBAAkB;EAS5B,KAXU,gBAAgB,YAAY,WAAW;EAYjD;EACA;EACA;EACA,MAAM;EACN;EACA;EACA;EACD"}