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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@websolutespa/bom-mixer-hooks

v1.9.2

Published

Mixer Hooks module of the BOM Repository

Readme

@websolutespa/bom-mixer-hooks

npm version

status alpha

Mixer Hooks module of the BOM Repository by websolute.


this library is for internal usage and not production ready

@websolutespa/bom-mixer-hooks Documentation

A collection of React hooks for building modern web applications.

Table of Contents

Installation

npm install @websolutespa/bom-mixer-hooks

API and Networking

useApi

Hook for making RESTful API calls.

import { useApi } from '@websolutespa/bom-mixer-hooks';

function MyComponent() {
  const api = useApi();

  const fetchData = async () => {
    try {
      // GET request
      const data = await api.get('/endpoint');

      // POST request with payload
      const response = await api.post('/endpoint', {
        name: 'John',
      });

      // PUT request
      await api.put('/endpoint/1', {
        updated: true,
      });

      // DELETE request
      await api.delete('/endpoint/1');
    } catch (error) {
      console.error('API error:', error);
    }
  };
}

useCollectionApi

Specialized version of useApi for data collections.

import { useCollectionApi, useCollectionApiGet } from '@websolutespa/bom-mixer-hooks';

function MyCollection() {
  const [data, loading, error] = useCollectionApiGet('/collection', {
    where: { status: 'active' }
  });

  if (loading) return <Loading />;
  if (error) return <Error message={error.message} />;

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

UI and Layout

useLayout

Manages the global application layout.

import { useLayout } from '@websolutespa/bom-mixer-hooks';

function Header() {
  const layout = useLayout();

  return (
    <header>
      <nav>
        {layout.menu.main.items.map(item => (
          <MenuItem key={item.id} {...item} />
        ))}
      </nav>
    </header>
  );
}

useDrawer

Manages drawer/sidebar state.

import { useDrawer } from '@websolutespa/bom-mixer-hooks';

function Sidebar() {
  const [drawer, openDrawer, closeDrawer] = useDrawer();

  return (
    <>
      <button onClick={() => openDrawer('main')}>Open Menu</button>

      <div className={`drawer ${drawer === 'main' ? 'open' : ''}`}>
        <button onClick={closeDrawer}>Close</button>
        {/* Drawer content */}
      </div>
    </>
  );
}

useBreakpoint

Handles responsive breakpoints.

import { useBreakpoint } from '@websolutespa/bom-mixer-hooks';

function ResponsiveComponent() {
  const breakpoint = useBreakpoint();

  return (
    <div>
      {breakpoint.key === 'xs' && <MobileView />}
      {breakpoint.key === 'md' && <TabletView />}
      {breakpoint.key === 'lg' && <DesktopView />}
    </div>
  );
}

Form and Input

useAutosizeTextArea

Automatically adjusts textarea height.

import { useAutosizeTextArea } from '@websolutespa/bom-mixer-hooks';

function AutoResizingTextarea() {
  const [value, setValue] = useState('');
  const textAreaRef = useRef<HTMLTextAreaElement>(null);

  useAutosizeTextArea(textAreaRef.current, value);

  return (
    <textarea
      ref={textAreaRef}
      value={value}
      onChange={(e) => setValue(e.target.value)}
    />
  );
}

useFocusTrap

Keeps focus within an element (useful for modals).

import { useFocusTrap } from '@websolutespa/bom-mixer-hooks';

function Modal() {
  const modalRef = useRef(null);
  const [isTrapped, setIsTrapped] = useFocusTrap(modalRef);

  useEffect(() => {
    setIsTrapped(true);
    return () => setIsTrapped(false);
  }, []);

  return (
    <div ref={modalRef}>
      <input type="text" />
      <button>Action</button>
      <button>Close</button>
    </div>
  );
}

Internationalization

useLabel

Manages translations.

import { useLabel } from '@websolutespa/bom-mixer-hooks';

function Translated() {
  const label = useLabel();

  return (
    <div>
      <h1>{label('welcome.title')}</h1>
      <p>{label('welcome.description', { name: 'John' })}</p>
    </div>
  );
}

useCurrency

Formats monetary values.

import { useCurrency } from '@websolutespa/bom-mixer-hooks';

function PriceDisplay() {
  const formatCurrency = useCurrency('EUR', 'en-US');

  return (
    <div>
      <p>Price: {formatCurrency(29.99)}</p> {/* Outputs: €29.99 */}
    </div>
  );
}

Scroll and Viewport

useIntersectionObserver

Observes when elements enter the viewport.

import { useIntersectionObserver } from '@websolutespa/bom-mixer-hooks';

function LazyImage() {
  const ref = useRef(null);
  const isVisible = useIntersectionObserver(ref, {
    threshold: 0.1
  });

  return (
    <div ref={ref}>
      {isVisible && <img src="heavy-image.jpg" alt="Lazy loaded" />}
    </div>
  );
}

useScrollTo

Manages smooth scrolling to elements.

import { useScrollTo } from '@websolutespa/bom-mixer-hooks';

function ScrollableContent() {
  const scrollTo = useScrollTo(80); // 80px offset

  return (
    <nav>
      <a href="#section1" onClick={scrollTo}>Go to Section 1</a>
      <div id="section1">
        {/* Content */}
      </div>
    </nav>
  );
}

State Management

useCurrentState

Manages state with current reference.

import { useCurrentState } from '@websolutespa/bom-mixer-hooks';

function StateManager() {
  const [value, setValue, valueRef] = useCurrentState(0);

  useEffect(() => {
    // valueRef.current is always up to date
    const interval = setInterval(() => {
      console.log('Current value:', valueRef.current);
    }, 1000);

    return () => clearInterval(interval);
  }, []);

  return (
    <button onClick={() => setValue(v => v + 1)}>
      Count: {value}
    </button>
  );
}

Performance

useDebounce

Delays function execution.

import { useDebounce } from '@websolutespa/bom-mixer-hooks';

function SearchInput() {
  const [value, setValue] = useState('');
  const debouncedValue = useDebounce(value, 500);

  useEffect(() => {
    // API call only after 500ms from last input
    searchAPI(debouncedValue);
  }, [debouncedValue]);

  return (
    <input
      type="text"
      value={value}
      onChange={(e) => setValue(e.target.value)}
    />
  );
}

Event Handling

useEventListener

Safely manages event listeners.

import { useEventListener } from '@websolutespa/bom-mixer-hooks';

function EventHandler() {
  const handleKeyPress = (e: KeyboardEvent) => {
    if (e.key === 'Escape') {
      // Handle escape key
    }
  };

  useEventListener('keydown', handleKeyPress);

  return <div>Press ESC to trigger action</div>;
}

Best Practices

  1. Hook Composition
function ComplexComponent() {
  const layout = useLayout();
  const breakpoint = useBreakpoint();
  const [drawer] = useDrawer();

  // Combine hooks for advanced functionality
  const isMobileMenuOpen = breakpoint.key === 'xs' && drawer === 'menu';

  return (
    <div className={isMobileMenuOpen ? 'mobile-menu' : ''}>
      {/* Component content */}
    </div>
  );
}
  1. Error Handling
function DataFetcher() {
  const [data, loading, error] = useCollectionApiGet('/api/data');

  if (error) {
    return <ErrorBoundary error={error} />;
  }

  if (loading) {
    return <LoadingSpinner />;
  }

  return <DataDisplay data={data} />;
}
  1. Performance Optimization
function OptimizedComponent() {
  const debouncedSearch = useDebounceCallback((term: string) => {
    searchAPI(term);
  }, 300);

  const intersectionRef = useRef(null);
  const isVisible = useIntersectionObserver(intersectionRef);

  // Load heavy content only when visible
  return (
    <div ref={intersectionRef}>
      {isVisible && <HeavyContent />}
    </div>
  );
}

Contributing

Please read our Contributing Guide before submitting a Pull Request to the project.

License

This project is licensed under the MIT License - see the LICENSE file for details.