475

useCounter

Hook that manages a counter

statelowtest coverage
GUESTS
2
For two
import { useCounter } from '@siberiacancode/reactuse';
import { MinusIcon, PlusIcon } from 'lucide-react';

import { cn } from '@/utils/lib';

const getGuestLabel = (count: number) => {
  if (count === 1) return 'Just you';
  if (count === 2) return 'For two';
  if (count <= 4) return 'Small group';
  if (count <= 7) return 'Medium group';
  return 'Large party';
};

const Demo = () => {
  const counter = useCounter(2, { min: 1, max: 10 });

  return (
    <div className='flex flex-col items-center gap-3'>
      <span className='text-muted-foreground text-sm font-medium tracking-widest'>GUESTS</span>

      <div className='flex items-center gap-6'>
        <button
          className={cn(counter.value <= 1 && 'opacity-25')}
          data-size='icon'
          data-variant='ghost'
          type='button'
          onClick={() => counter.dec()}
        >
          <MinusIcon strokeWidth={1.5} />
        </button>

        <span className='w-26 text-center text-7xl font-light tabular-nums'>{counter.value}</span>

        <button
          className={cn(counter.value >= 10 && 'opacity-25')}
          data-size='icon'
          data-variant='ghost'
          type='button'
          onClick={() => counter.inc()}
        >
          <PlusIcon strokeWidth={1.5} />
        </button>
      </div>

      <span className='text-muted-foreground text-sm'>{getGuestLabel(counter.value)}</span>
    </div>
  );
};

export default Demo;

Installation

pnpm add @siberiacancode/reactuse

Usage

const { count, dec, inc, reset, set } = useCounter(5);
// or
const { count, dec, inc, reset, set } = useCounter({ initialValue: 5, min: 0, max: 10 });

Type Declarations

import type { Dispatch, SetStateAction } from 'react';

export interface UseCounterOptions {
  /** The max of count value */
  max?: number;
  /** The min of count value */
  min?: number;
}

export interface UseCounterReturn {
  /** Function to set a specific value to the counter */
  set: Dispatch<SetStateAction<number>>;
  /** The current count value */
  value: number;
  /** Function to decrement the counter */
  dec: (value?: number) => void;
  /** Function to increment the counter */
  inc: (value?: number) => void;
  /** Function to reset the counter to its initial value. */
  reset: () => void;
}

export interface UseCounter {
  (initialValue?: number, options?: UseCounterOptions): UseCounterReturn;

  (options: UseCounterOptions & { initialValue?: number }, initialValue?: never): UseCounterReturn;
}

API

Parameters

NameTypeDefaultNote
initialValuenumber0The initial number value
options.minnumberNumber.NEGATIVE_INFINITYThe min of count value
options.maxnumberNumber.POSITIVE_INFINITYThe max of count value

Returns

UseCounterReturn

Parameters

NameTypeDefaultNote
params.initialValuenumber0The initial number value
params.minnumberNumber.NEGATIVE_INFINITYThe min of count value
params.maxnumberNumber.POSITIVE_INFINITYThe max of count value

Returns

UseCounterReturn

Contributors

ddebabin

Last updated on