useCounterSelection - Increment and Decrement number with fp-ts

Sandro Maglione

Sandro Maglione

Web development

This hook is an abstraction for storing a number value that can be incremented and decremented by a given amount of steps.

This hook uses Option and pipe from fp-ts.

useCounterSelection.ts
import { pipe } from "fp-ts/lib/function";
import * as O from "fp-ts/Option";
import { useState } from "react";
 
interface UseCounterProps {
  minValue?: number;
  maxValue?: number;
  selectedValueDefault: number;
  step?: number;
}
 
/**
 * Store a `number` value that can be incremented/decremented by the given amount of `step`.
 */
export const useCounterSelection = ({
  selectedValueDefault,
  maxValue,
  minValue,
  step = 1,
}: UseCounterProps): {
  selectedValue: number;
  onAddSelectedValue: () => void;
  onSubtractSelectedValue: () => void;
} => {
  const [selectedValue, setSelectedValue] = useState(selectedValueDefault);
 
  const onAddSelectedValue = (): void => {
    pipe(
      maxValue,
      O.fromNullable,
      O.fold(
        () => {
          setSelectedValue((v) => v + step);
        },
        (max) => {
          setSelectedValue((v) => Math.min(v + step, max));
        }
      )
    );
  };
 
  const onSubtractSelectedValue = (): void => {
    pipe(
      minValue,
      O.fromNullable,
      O.fold(
        () => {
          setSelectedValue((v) => v - step);
        },
        (min) => {
          setSelectedValue((v) => Math.max(v - step, min));
        }
      )
    );
  };
 
  return {
    selectedValue,
    onAddSelectedValue,
    onSubtractSelectedValue,
  };
};

đŸ‘‹ăƒ»Interested in learning more, every week?

Every week I build a new open source project, with a new language or library, and teach you how I did it, what I learned, and how you can do the same. Join me and other 600+ readers.