npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@denovo-hellas/common

v1.2.3

Published

Common functions and hooks

Downloads

469

Readme

useArray Hook

The useArray hook provides a set of utility functions to manage and manipulate an array state in a React component. It leverages the useState hook to maintain the state of the array and offers methods for common operations like adding, filtering, updating, and removing elements from the array.

TypeScript Definition

function useArray<T>(defaultValue: T[]): {
  data: T[];
  set: React.Dispatch<React.SetStateAction<T[]>>;
  push: (element: T) => void;
  filter: (callback: (element: T, index: number, array: T[]) => boolean) => void;
  update: (index: number, newElement: T) => void;
  remove: (index: number) => void;
  clear: () => void;
  updateAll: (callback: (element: T, index: number, array: T[]) => T) => void;
}

Usage

import useArray from './useArray';

function MyComponent() {
  const { data, push, remove, update, clear, filter, updateAll } = useArray<number>([]);

  // Example usage:
  push(5); // Adds 5 to the array
  update(0, 10); // Updates the first element to 10
  remove(0); // Removes the first element
  clear(); // Clears the entire array
  filter((element) => element > 10); // Keeps elements greater than 10
  updateAll((element) => element * 2); // Doubles every element in the array

  return (
    <div>
      {data.map((item, index) => (
        <div key={index}>{item}</div>
      ))}
    </div>
  );
}

Parameters

  • defaultValue: T[]: The initial value of the array. It sets up the initial state of the array.

Returns

The useArray hook returns an object containing the following properties and methods:

Properties

  • data: T[]: The current state of the array.
  • set: React.Dispatch<React.SetStateAction<T[]>>: A setter function to directly update the state of the array, similar to useState.

Methods

  • push(element: T): void

    • Adds a new element to the end of the array.
    • Parameters: element - The element to add to the array.
  • filter(callback: (element: T, index: number, array: T[]) => boolean): void

    • Filters the array based on the provided callback function, keeping only the elements for which the callback returns true.
    • Parameters: callback - A function that receives each element, its index, and the entire array, and returns a boolean indicating whether the element should remain in the array.
  • update(index: number, newElement: T): void

    • Updates the element at the specified index with a new element.
    • Parameters:
      • index - The index of the element to update.
      • newElement - The new element to replace the existing one.
  • remove(index: number): void

    • Removes the element at the specified index from the array.
    • Parameters: index - The index of the element to remove.
  • clear(): void

    • Clears the entire array, setting it to an empty array.
  • updateAll(callback: (element: T, index: number, array: T[]) => T): void

    • Updates all elements in the array using the provided callback function.
    • Parameters: callback - A function that receives each element, its index, and the entire array, and returns a new value for each element.

Example Use Cases

  • Managing a dynamic list of items, such as a to-do list where you can add, remove, and update tasks.
  • Filtering or transforming data, for example, filtering out specific values or modifying all elements with a given transformation.

Notes

  • This hook makes managing arrays in React state more convenient by abstracting common operations into easy-to-use functions.
  • The useArray hook can be used with any type T, making it a generic and reusable utility for managing arrays of different types (e.g., strings, numbers, objects).

useAsyncOnce Hook

Function Signature

export function useAsyncOnce<T extends (...args: any[]) => Promise<any>>(asyncFunction: T): UseAsyncOnceProps<T> { ... }

Parameters

  • asyncFunction: An asynchronous function of type T that you want to execute. This function can take any number of arguments and must return a Promise.

Returns

An object of type UseAsyncOnceProps<T> containing:

  • call: A function that invokes asyncFunction. This function accepts the same parameters as asyncFunction.
  • isExecuting: A boolean value that indicates whether asyncFunction is currently being executed.

Usage Example

import React from 'react';
import { useAsyncOnce } from '@/hooks/useAsyncOnce';

async function fetchData() {
  // Simulating an async data fetch
  return await fetch('https://api.example.com/data');
}

function MyComponent() {
  const { call, isExecuting } = useAsyncOnce(fetchData);

  return (
    <div>
      <button onClick={call} disabled={isExecuting}>
        {isExecuting ? 'Loading...' : 'Fetch Data'}
      </button>
    </div>
  );
}

Detailed Explanation

State Management

  • isExecuting: A boolean state, managed using useState, that tracks whether the asyncFunction is currently being executed. It is initialized to false.

call Function

  • useCallback is used to memoize the call function, ensuring that it only changes when asyncFunction or isExecuting changes.
  • The call function performs the following:
    • Checks if isExecuting is true. If it is, the function returns early, preventing multiple simultaneous executions.
    • Sets isExecuting to true before calling asyncFunction.
    • Uses a try-catch-finally block to:
      • Await the execution of asyncFunction.
      • Log an error to the console if the call fails.
      • Reset isExecuting to false when the function completes, regardless of success or failure.

Benefits

  • Prevents multiple simultaneous calls: By using isExecuting, the hook ensures that asyncFunction isn't called again until the previous execution finishes.
  • Handles state management: Automatically updates isExecuting to inform your components when the function is running.

useDebounce Hook

The useDebounce hook is a utility for debouncing a callback function, which limits the rate at which the function is invoked. This is useful in scenarios where frequent events (such as typing or scrolling) would otherwise cause a function to run too many times. The hook ensures that the callback is only called after the specified delay has elapsed since the last time the hook dependencies were updated.

Function Signature

export default function useDebounce({ callback, delay, dependencies }: UseDebounceProps): void

Parameters

  • callback: Function
    The function to be debounced. This is the function that will be called after the specified delay if no dependencies change during that time.

  • delay: number
    The delay in milliseconds that the hook will wait after the last change in dependencies before calling callback.

  • dependencies: Array<any>
    An array of dependencies that, when changed, will reset the debounce timer. This is similar to the dependency array in useEffect.

Return Value

The useDebounce hook does not return a value.

How It Works

  • useTimeout is used internally to set up a timer. This timer is configured to trigger the callback function after the delay.
  • reset and clear are utility functions provided by useTimeout:
    • reset restarts the timer every time there is a change in any of the dependencies.
    • clear stops the timer when the component is unmounted.

Example Usage

import useDebounce from './useDebounce';

function SearchComponent({ searchTerm }) {
  const debouncedSearch = () => {
    // Perform search logic here, e.g., API call
    console.log('Searching:', searchTerm);
  };

  // Set up debounce with a 500ms delay
  useDebounce({
    callback: debouncedSearch,
    delay: 500,
    dependencies: [searchTerm],
  });

  return <div>{/* Your component UI */}</div>;
}

In this example:

  • debouncedSearch is only called 500ms after the last searchTerm update.
  • If searchTerm changes before 500ms have passed, the timer resets.

useTimeout Hook

The useTimeout hook provides a utility for managing a timeout in React. It allows you to set a timeout that will execute a callback function after a specified delay and offers methods to reset or clear the timeout.

Function Signature

export default function useTimeout({ callback, delay }: UseTimeoutProps): { reset: () => void; clear: () => void }

Parameters

  • callback: Function
    The function to be executed after the specified delay. This callback is invoked only once per timeout interval, or each time reset is called.

  • delay: number
    The amount of time, in milliseconds, to wait before calling the callback function.

Return Value

The useTimeout hook returns an object with the following methods:

  • reset: Function
    A function to reset the timeout. This will clear the existing timeout (if any) and start a new one based on the delay parameter.

  • clear: Function
    A function to clear the timeout. This stops the timeout from executing the callback function if it hasn’t already executed.

How It Works

Internally, the hook manages a timeout using the following techniques:

  • useRef is used to store references to the callback and timeout.
  • useCallback memoizes the set, clear, and reset functions to ensure that they are stable across renders.
  • useEffect:
    • Updates callbackRef whenever callback changes, ensuring the latest function is called even if the timeout is still active.
    • Automatically sets the timeout when the component mounts and clears it on unmount or if delay changes.

Example Usage

import useTimeout from './useTimeout';

function Notification({ message, duration }) {
  const { reset, clear } = useTimeout({
    callback: () => {
      alert('Timeout expired!');
    },
    delay: duration,
  });

  return (
    <div>
      <p>{message}</p>
      <button onClick={reset}>Reset Timeout</button>
      <button onClick={clear}>Clear Timeout</button>
    </div>
  );
}

In this example:

  • A timeout is set to show an alert after duration milliseconds.
  • The "Reset Timeout" button restarts the timeout when clicked, while the "Clear Timeout" button stops the timeout, preventing the alert from being displayed.

useEventListener Hook

The useEventListener hook is a custom React hook that simplifies attaching and managing event listeners on a specified element. It supports dynamically updating the callback function and ensures cleanup on unmount, making it especially useful for handling DOM events in React.

Function Signature

export function useEventListener({ eventType, callback, element }: UseEventListenerProps): void

Parameters

  • eventType: string
    The type of event to listen for (e.g., "click", "scroll", "resize").

  • callback: Function
    The function to be executed when the event is triggered. The callback receives the event object as its argument.

  • element: RefObject<HTMLElement> | Window | null
    The target element to which the event listener will be attached. This can be a React ref for a DOM element, window, or null (in which case no event listener is attached).

Return Value

This hook does not return any value.

How It Works

  • callbackRef is a useRef hook that holds a reference to the latest callback function, ensuring that the most recent version is called without needing to re-register the event listener each time callback updates.
  • useEffect:
    • Updates callbackRef.current whenever callback changes.
    • Registers the event listener on the specified element:
      • For window elements, it directly attaches the listener.
      • For DOM elements passed as ref, it uses element.current to add and remove the listener.
    • Cleans up the event listener on component unmount or when eventType or element changes.

Example Usage

import { useRef } from 'react';
import { useEventListener } from './useEventListener';

function ClickTracker() {
  const divRef = useRef(null);

  useEventListener({
    eventType: 'click',
    callback: (e) => console.log('Div clicked!', e),
    element: divRef,
  });

  return <div ref={divRef} style={{ width: '200px', height: '200px', background: 'lightblue' }}>Click me!</div>;
}

In this example:

  • The useEventListener hook adds a click event listener to a div element, which logs a message to the console each time the div is clicked.
  • The hook ensures that the event listener is cleaned up if the component unmounts or the eventType or element changes.

useStateWithHistory Hook

The useStateWithHistory hook provides a way to manage state with history tracking, allowing you to navigate backward and forward through previous state values. This is useful in scenarios where users might want to undo or redo actions, similar to browser navigation or an editor's history feature.


## Function Signature

```typescript
export default function useStateWithHistory<T>({
  defaultValue,
  capacity = 10,
}: StateWithHistoryProps<T>): StateWithHistory<T>

Parameters

  • defaultValue: T
    The initial value of the state.

  • capacity: number (optional, default = 10)
    The maximum number of historical states to keep in memory. When the history exceeds this capacity, the oldest entries are removed.

Return Value

The hook returns an object with the following properties and functions:

  • value: T
    The current state value.

  • set: (v: T) => void
    Function to set a new state value. If the new value is different from the current state, it is added to the history.

  • history: T[]
    An array representing the history of state values.

  • pointer: number
    The current position in the history, indicating which version of the state is currently active.

  • back: () => void
    Function to move one step back in the history. If already at the oldest state, it has no effect.

  • forward: () => void
    Function to move one step forward in the history. If already at the latest state, it has no effect.

  • go: (index: number) => void
    Function to go to a specific position in the history by index. If the index is out of range, it has no effect.

How It Works

  • State Management: The useState hook manages the primary state (value).
  • History Tracking:
    • historyRef holds the array of historical state values.
    • pointerRef keeps track of the current position within historyRef.
    • The set function updates the state and manages the history, clearing any "future" states if a new value is set after moving back in history.
  • Capacity Management: When the number of historical states exceeds capacity, the oldest state is removed.

Example Usage

import useStateWithHistory from './useStateWithHistory';

function Counter() {
  const {
    value,
    set,
    history,
    pointer,
    back,
    forward,
    go,
  } = useStateWithHistory({ defaultValue: 0, capacity: 5 });

  return (
    <div>
      <p>Current Value: {value}</p>
      <button onClick={() => set(value + 1)}>Increment</button>
      <button onClick={() => set(value - 1)}>Decrement</button>
      <button onClick={back} disabled={pointer <= 0}>Undo</button>
      <button onClick={forward} disabled={pointer >= history.length - 1}>Redo</button>
      <p>History: {history.join(', ')}</p>
    </div>
  );
}

In this example:

  • Increment and Decrement buttons modify the current state.
  • Undo and Redo buttons navigate backward and forward through state history, allowing for easy state management and history tracking.
  • The history array shows the current state history, with pointer indicating the current position in that history.

isOnScreen Hook

The isOnScreen hook determines if a specified element is visible on the screen using the Intersection Observer API. This is useful for detecting when an element enters or leaves the viewport, enabling features like lazy loading, animations, or analytics tracking.

## Function Signature

```typescript
export function isOnScreen(ref: RefObject<HTMLElement>, rootMargin = '0px'): boolean

Parameters

  • ref: RefObject<HTMLElement>
    A React ref object pointing to the DOM element to observe. This ref should be attached to an element in the component.

  • rootMargin: string (optional, default = '0px')
    The margin around the root (viewport) that is used to determine visibility. This parameter accepts values similar to CSS margin (e.g., '10px 20px'). Increasing the root margin can trigger visibility checks earlier (when the element is still outside the viewport).

Return Value

  • isVisible: boolean
    Returns true if the element is currently visible on the screen (within the viewport) and false otherwise.

How It Works

  • The hook uses an IntersectionObserver to monitor the visibility of the specified ref element.
  • When the element's visibility changes (enters or exits the viewport based on rootMargin), the observer's callback updates the isVisible state.
  • Cleanup: The observer disconnects automatically when the component unmounts or if ref changes, preventing memory leaks.

Example Usage

import { useRef } from 'react';
import { isOnScreen } from './isOnScreen';

function ImageWithLazyLoad() {
  const imageRef = useRef(null);
  const onScreen = isOnScreen(imageRef, '100px'); // Trigger 100px before entering viewport

  return (
    <div ref={imageRef} style={{ height: '300px', background: 'lightgray' }}>
      {onScreen ? <img src="image.jpg" alt="Lazy loaded image" /> : <p>Scroll to load image</p>}
    </div>
  );
}

In this example:

  • The isOnScreen hook detects if imageRef is within 100px of the viewport, allowing the image to load just before it enters the screen.
  • If the element is not in view, a placeholder text is displayed instead.

useAnimatedNumber Hook

The useAnimatedNumber hook animates a numeric value from a starting value to a target value over a specified duration. It supports options for decimal values, locale-based formatting, and re-triggering the animation when the element comes into view.


## Function Signature

```typescript
export function useAnimatedNumber(
  targetValue: number,
  ref: React.RefObject<HTMLElement>,
  options: UseAnimatedNumberOptions = {}
): string

Parameters

  • targetValue: number
    The target value to animate to.

  • ref: React.RefObject<HTMLElement>
    A React ref object pointing to the DOM element that should be observed. The animation can be triggered when this element enters the viewport.

  • options: UseAnimatedNumberOptions (optional)
    An object to configure animation options.

    • startValue: number (default = 0)
      The initial value of the animation.

    • duration: number (default = 1000)
      The duration of the animation in milliseconds.

    • isDecimal: boolean (default = false)
      Specifies whether the animated value should be displayed as a decimal.

    • locale: string (default = 'en')
      The locale used for formatting the animated number, allowing for proper number formatting based on the user’s locale.

    • retriggerOnView: boolean (default = false)
      If set to true, the animation re-triggers each time the element enters the viewport.

Return Value

  • parsedToLocaleNumber: string
    A string representing the animated number formatted to the specified locale.

How It Works

  • View Triggering: The hook uses the isOnScreen helper to check if the element referenced by ref is in view, triggering the animation when it appears in the viewport.
  • Animation Calculation:
    • Uses requestAnimationFrame to update the value over time.
    • Calculates progress based on the duration and animates from startValue to targetValue.
    • If isDecimal is true, the value is formatted as a decimal.
  • Locale Formatting: The Intl.NumberFormat API is used to format the animated value according to the specified locale.
  • Re-triggering: The retriggerOnView option determines if the animation re-triggers when the element re-enters the viewport.

Example Usage

import { useRef } from 'react';
import { useAnimatedNumber } from './useAnimatedNumber';

function AnimatedCounter() {
  const counterRef = useRef(null);
  const animatedNumber = useAnimatedNumber(100, counterRef, {
    startValue: 0,
    duration: 2000,
    isDecimal: true,
    locale: 'en',
    retriggerOnView: true,
  });

  return (
    <div ref={counterRef} style={{ fontSize: '2rem', fontWeight: 'bold' }}>
      {animatedNumber}
    </div>
  );
}

In this example:

  • The number animates from 0 to 100 over 2000 milliseconds, displaying as a decimal with a locale-specific format.
  • The animation re-triggers each time the element comes back into view.

useDialog Hook

The useDialog hook provides a convenient way to manage the open and close states of a dialog component. This hook centralizes the dialog state management, providing functions to easily open, close, and toggle the dialog state.


## Function Signature

```typescript
export function useDialog({ open: openProps = false }: UseDialogProps = {}): {
  open: boolean;
  setDialogOpen: () => void;
  setDialogClose: () => void;
  setOpen: (open: boolean) => void;
}

Parameters

  • props: UseDialogProps (optional)
    An object to configure the initial dialog state.

    • open: boolean (default = false)
      The initial state of the dialog (open or closed).

Return Value

The hook returns an object containing the current dialog state and functions to control it:

  • open: boolean
    The current open state of the dialog. true means the dialog is open; false means it is closed.

  • setDialogOpen: () => void
    A function to set the open state to true, opening the dialog.

  • setDialogClose: () => void
    A function to set the open state to false, closing the dialog.

  • setOpen: (open: boolean) => void
    A function to set the open state directly, allowing for more flexible state control.

How It Works

  • State Management:
    • The useState hook initializes the dialog state (open) based on the open parameter in props.
    • setOpen provides a direct way to modify the state.
  • Convenience Functions:
    • setDialogOpen and setDialogClose simplify toggling the dialog, especially useful for event handlers or dialog controls.

Example Usage

import { useDialog } from './useDialog';

function ExampleDialog() {
  const { open, setDialogOpen, setDialogClose } = useDialog({ open: false });

  return (
    <div>
      <button onClick={setDialogOpen}>Open Dialog</button>
      {open && (
        <div className="dialog">
          <p>This is the dialog content.</p>
          <button onClick={setDialogClose}>Close Dialog</button>
        </div>
      )}
    </div>
  );
}

In this example:

  • Open Dialog button calls setDialogOpen to open the dialog.
  • Close Dialog button inside the dialog calls setDialogClose to close it.
  • The open variable controls the conditional rendering of the dialog component.