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 🙏

© 2025 – Pkg Stats / Ryan Hefner

everyday-helper

v1.2.3

Published

A lightweight collection of React hooks, utility functions, and helpers for modern React development

Downloads

2,498

Readme

everyday-helper

A lightweight collection of React hooks, utility functions, and helpers that'll make your development workflow smoother. This package brings together commonly needed utilities so you don't have to reinvent the wheel every time you start a new project.

Contributing

Feel free to open issues or submit pull requests if you find bugs or have suggestions for improvements!

What's Inside?

This package is organized into four main sections:

  • Hooks - React hooks for common patterns
  • Utils - Pure utility functions for data manipulation
  • Lib - Helper libraries for specific tasks
  • Constants - Predefined constant values

Library Helpers

FormDataBuilder

Build FormData objects with ease.

import { createFormData } from 'everyday-helper/lib';

const formData = createFormData()
  .append('name', 'John')
  .append('email', '[email protected]')
  .appendFile('avatar', avatarFile)
  .appendJSON('metadata', { age: 30 })
  .appendArray('tags', [{ id: 1, name: 'tech' }])
  .build();

// With options
const formData2 = createFormData({
  skipNull: true,
  skipUndefined: true,
  skipEmptyStrings: true,
})
  .appendFields({ name: 'John', age: 30 })
  .build();

Storage Lib

Type-safe localStorage and sessionStorage wrappers.

import { local, session } from 'everyday-helper/lib';

// Local storage
local.set('user', { id: 1, name: 'John' });
const user = local.get<User>('user');
const userOrDefault = local.getOr('user', { id: 0, name: 'Guest' });
local.remove('user');
local.clear();

// Session storage
session.set('temp_data', { foo: 'bar' });
const data = session.get('temp_data');
session.has('temp_data'); // true
const allKeys = session.keys();

cn - Class Name Utility

Conditionally combine class names.

import cn from 'everyday-helper/lib';

function Button({ isActive, isPrimary, className }) {
  return (
    <button
      className={cn(
        'btn',
        {
          active: isActive,
          'btn-primary': isPrimary,
        },
        className,
      )}
    >
      Click me
    </button>
  );
}

CookieManager

Simple cookie management.

import { CookieManager } from 'everyday-helper/lib';

// Set cookie
CookieManager.set('user_token', 'abc123', {
  domain: '.example.com',
  path: '/',
  expires: 7, // 7 days
  secure: true,
  sameSite: 'Strict',
});

// Get cookie
const token = CookieManager.get('user_token');

// Remove cookie
CookieManager.remove('user_token');

lazyLoad

Lazy load React components with retry logic.

import lazyLoad from 'everyday-helper/lib';

const components = lazyLoad(
  {
    HomePage: () => import('./pages/Home'),
    AboutPage: () => import('./pages/About'),
    Dashboard: () => import('./pages/Dashboard'),
  },
  {
    retries: 2,
    delayMs: 250,
  },
);

function App() {
  return (
    <Suspense fallback={<Loading />}>
      <Routes>
        <Route path="/" element={<components.HomePage />} />
        <Route path="/about" element={<components.AboutPage />} />
      </Routes>
    </Suspense>
  );
}

React Hooks

usePortal

Create a portal container dynamically for modals, tooltips, etc.

import { usePortal } from 'everyday-helper/hooks';
import { createPortal } from 'react-dom';

function Modal({ children }) {
  const portalRef = usePortal({ id: 'modal-root' });

  if (!portalRef.current) return null;

  return createPortal(children, portalRef.current);
}

useAppLocation

A wrapper around React Router's useLocation that provides convenient methods for working with the current route.

import { useAppLocation } from 'everyday-helper/hooks';

function NavBar() {
  const { pathname, isActive, includes, startsWith } = useAppLocation();

  return (
    <nav>
      <a className={isActive('/home') ? 'active' : ''}>Home</a>
      <a className={includes('/dashboard') ? 'active' : ''}>Dashboard</a>
      <a className={startsWith('/admin') ? 'active' : ''}>Admin</a>
    </nav>
  );
}

Returns:

  • pathname - Current pathname
  • hash - URL hash
  • search - URL search params
  • isActive(path) - Check if path exactly matches current pathname
  • includes(segment) - Check if pathname includes a segment
  • startsWith(prefix) - Check if pathname starts with a prefix

useDebounce

Debounces a value, useful for search inputs or expensive operations.

import { useDebounce } from 'everyday-helper/hooks';

function SearchBar() {
  const [searchTerm, setSearchTerm] = useState('');
  const debouncedSearch = useDebounce(searchTerm, 500);

  useEffect(() => {
    // This only runs 500ms after user stops typing
    if (debouncedSearch) {
      fetchSearchResults(debouncedSearch);
    }
  }, [debouncedSearch]);

  return <input value={searchTerm} onChange={(e) => setSearchTerm(e.target.value)} />;
}

Parameters:

  • value - The value to debounce
  • delay - Delay in milliseconds (default: 500)

useDownloadFile

Provides a simple way to download images from URLs.

import { useDownloadFile } from 'everyday-helper/hooks';

function ImageGallery() {
  const { downloadImage } = useDownloadFile();

  return (
    <button onClick={() => downloadImage('/api/image.jpg', 'my-image')}>Download Image</button>
  );
}

Methods:

  • downloadImage(src, filename) - Downloads image as PNG file

useEscapeKey

Execute a callback when the Escape key is pressed.

import { useEscapeKey } from 'everyday-helper/hooks';

function Modal({ onClose }) {
  useEscapeKey({
    onEscape: onClose,
    enabled: true,
    preventDefault: true,
  });

  return <div className="modal">...</div>;
}

Props:

  • onEscape - Callback function to execute
  • enabled - Whether the hook is active (default: true)
  • preventDefault - Prevent default behavior (default: false)

useEventListener

Attach event listeners to window or document with automatic cleanup.

import { useEventListener } from 'everyday-helper/hooks';

function Component() {
  useEventListener('scroll', () => {
    console.log('User scrolled!');
  });

  useEventListener('click', handleClick, document);

  return <div>...</div>;
}

Parameters:

  • event - Event name
  • handler - Event handler function
  • element - Target element (default: window)

useOnlineStatus

Track the user's online/offline status in real-time.

import { useOnlineStatus } from 'everyday-helper/hooks';

function ConnectionStatus() {
  const isOnline = useOnlineStatus();

  return (
    <div className={isOnline ? 'online' : 'offline'}>
      {isOnline ? 'Connected' : 'No internet connection'}
    </div>
  );
}

useOutsideClick

Detect clicks outside a specific element.

import { useOutsideClick } from 'everyday-helper/hooks';
import { useRef } from 'react';

function Dropdown() {
  const dropdownRef = useRef(null);
  const [isOpen, setIsOpen] = useState(false);

  useOutsideClick(dropdownRef, () => setIsOpen(false));

  return <div ref={dropdownRef}>{/* Clicking outside closes the dropdown */}</div>;
}

Options:

  • id - Target element ID (if not provided, appends to body)

usePrevious

Keep track of a value from the previous render.

import { usePrevious } from 'everyday-helper/hooks';

function Counter() {
  const [count, setCount] = useState(0);
  const prevCount = usePrevious(count);

  return (
    <div>
      <p>Current: {count}</p>
      <p>Previous: {prevCount}</p>
    </div>
  );
}

usePrint

Print images with customizable styling in a new window or iframe.

import { usePrint } from 'everyday-helper/hooks';

function ImageViewer({ imageUrl }) {
  const { printInBlank, printInCurrent } = usePrint();

  return (
    <>
      <button onClick={() => printInBlank(imageUrl, { padding: '20px' })}>
        Print in New Window
      </button>
      <button onClick={() => printInCurrent(imageUrl, { fit: 'contain' })}>
        Print in Current Page
      </button>
    </>
  );
}

Methods:

  • printInBlank(src, style?) - Opens print dialog in new window
  • printInCurrent(src, style?) - Prints using hidden iframe

Style Options:

  • padding - Padding around image (default: '20px')
  • fit - Object-fit value (default: 'contain')
  • maxWidth - Maximum width (default: '100%')
  • maxHeight - Maximum height (default: '100%')
  • background - Background color (default: '#fff')
  • printDelay - Delay before printing (default: 150ms)
  • cleanupDelay - Cleanup delay for iframe (default: 10000ms)

useResizeListener

Listen for window resize events with optional activation control.

import { useResizeListener } from 'everyday-helper/hooks';

function ResponsiveComponent() {
  const [width, setWidth] = useState(window.innerWidth);

  useResizeListener(() => {
    setWidth(window.innerWidth);
  }, true);

  return <div>Window width: {width}px</div>;
}

useScrollLock

Lock/unlock body scroll, perfect for modals and overlays.

import { useScrollLock } from 'everyday-helper/hooks';

function Modal({ isOpen }) {
  useScrollLock({ isLocked: isOpen });

  return isOpen ? <div className="modal">...</div> : null;
}

useToggle

Simple toggle state management with helpful methods.

import { useToggle } from 'everyday-helper/hooks';

function Accordion() {
  const { isActive, toggle, onOpen, onClose } = useToggle();

  return (
    <div>
      <button onClick={toggle}>Toggle</button>
      <button onClick={onOpen}>Open</button>
      <button onClick={onClose}>Close</button>
      {isActive && <div>Accordion content</div>}
    </div>
  );
}

Returns:

  • isActive - Current state (boolean)
  • toggle() - Toggle the state
  • onOpen() - Set to true
  • onClose() - Set to false

Utility Functions

Array Utils

Working with arrays made easier.

import {
  uniqueBy,
  groupBy,
  chunk,
  first,
  last,
  shuffle,
  sortBy,
  partition,
} from 'everyday-helper/utils';

// Remove duplicates by key
const users = uniqueBy(allUsers, 'id');

// Group items by property
const usersByRole = groupBy(users, 'role');
// { admin: [...], user: [...] }

// Split into chunks
const pages = chunk(items, 10); // [[1-10], [11-20], ...]

// Get first/last elements
const firstUser = first(users);
const lastUser = last(users);

// Shuffle array randomly
const randomOrder = shuffle(items);

// Sort by key or function
const sorted = sortBy(users, 'name', 'asc');
const custom = sortBy(users, (u) => u.age, 'desc');

// Partition based on condition
const [active, inactive] = partition(users, (u) => u.isActive);

Available functions:

  • uniqueBy(arr, key) - Unique elements by property
  • groupBy(arr, key) - Group by property
  • chunk(arr, size) - Split into chunks
  • checkArrEquality(arr1, arr2) - Deep equality check
  • reverseArr(arr) - Reverse array
  • reject(arr, predicate) - Opposite of filter
  • count(arr, predicate?) - Count matching elements
  • pushIf(arr, element, condition) - Conditional push
  • first(arr) - First element
  • last(arr) - Last element
  • unique(arr) - Unique primitives
  • flatten(arr) - Flatten one level
  • flattenDeep(arr) - Flatten all levels
  • compactArr(arr) - Remove falsy values
  • sample(arr) - Random element
  • sampleSize(arr, n) - N random elements
  • shuffle(arr) - Randomize order
  • difference(arr1, arr2) - Elements in arr1 not in arr2
  • intersection(arr1, arr2) - Common elements
  • union(arr1, arr2) - All unique elements
  • without(arr, ...values) - Remove specific values
  • zip(...arrays) - Zip arrays into tuples
  • fromPairs(pairs) - Create object from pairs
  • sum(arr) - Sum of numbers
  • average(arr) - Average of numbers
  • min(arr) - Minimum value
  • max(arr) - Maximum value
  • partition(arr, predicate) - Split by condition
  • sortBy(arr, keyOrFn, order) - Sort by key/function

String Utils

Comprehensive string manipulation utilities.

import {
  capitalize,
  truncate,
  slugify,
  toCamelCase,
  toPascalCase,
  toSnakeCase,
  toKebabCase,
} from 'everyday-helper/utils';

// Case transformations
const camel = toCamelCase('hello-world'); // 'helloWorld'
const pascal = toPascalCase('hello-world'); // 'HelloWorld'
const snake = toSnakeCase('HelloWorld'); // 'hello_world'
const kebab = toKebabCase('HelloWorld'); // 'hello-world'

// Text formatting
const title = capitalize('hello'); // 'Hello'
const short = truncate('Long text here', 10); // 'Long te...'
const url = slugify('Hello World!'); // 'hello-world'

// String checks
const similar = isStringSimilar('dashbord', 'dashboard', 2); // true
const hasMatch = includesIgnoreCase('Hello World', 'WORLD'); // true
const isEqual = eqIgnoreCase('Hello', 'hello'); // true

Available functions:

  • isStringSimilar(input, target, maxDiff) - Fuzzy string matching
  • concatIf(s1, s2, condition) - Conditional concatenation
  • isString(v) - Type check
  • eqIgnoreCase(s1, s2) - Case-insensitive equality
  • includesIgnoreCase(s1, s2) - Case-insensitive includes
  • addAsteriskIf(s, condition) - Conditional asterisk
  • compactStr(s) - Remove all whitespace
  • toUpperSnakeCase(str) - UPPER_SNAKE_CASE
  • toSnakeCase(str) - snake_case
  • toCamelCase(str) - camelCase
  • toPascalCase(str) - PascalCase
  • toKebabCase(str) - kebab-case
  • capitalize(str) - Capitalize first letter
  • capitalizeWords(str) - Capitalize each word
  • truncate(str, maxLength, suffix) - Truncate with ellipsis
  • reverse(str) - Reverse string
  • countOccurrences(str, substr) - Count substring
  • normalizeWhitespace(str) - Normalize spaces
  • padStart/padEnd(str, length, char) - Pad string
  • trim/trimStart/trimEnd(str, chars) - Trim characters
  • startsWith/endsWith(str, search, ignoreCase) - String checks
  • repeat(str, count) - Repeat string
  • slugify(str) - URL-friendly string

Object Utils

Powerful object manipulation utilities.

import {
  pick,
  omit,
  get,
  set,
  merge,
  deepMerge,
  cleanObject,
  mapValues,
} from 'everyday-helper/utils';

const user = {
  id: 1,
  name: 'John',
  email: '[email protected]',
  role: 'admin',
  metadata: { age: 30 },
};

// Pick specific keys
const basicInfo = pick(user, ['name', 'email']);
// { name: 'John', email: '[email protected]' }

// Omit keys
const withoutEmail = omit(user, ['email']);

// Get nested values safely
const age = get(user, 'metadata.age', 0); // 30

// Set nested values
set(user, 'metadata.city', 'NYC');

// Merge objects
const updated = merge(user, { status: 'active' });
const deepMerged = deepMerge(user, { metadata: { location: 'US' } });

// Clean empty values
const cleaned = cleanObject({ name: 'John', email: '', age: null });
// { name: 'John' }

// Transform values
const uppercased = mapValues(user, (val) => (typeof val === 'string' ? val.toUpperCase() : val));

Available functions:

  • pick(obj, keys) - Select specific keys
  • omit(obj, keys) - Remove specific keys
  • merge(target, source) - Shallow merge
  • cleanObject(obj) - Remove null/undefined/empty
  • areAllValuesComplete(obj) - Check if all values are filled
  • isObject(o) - Type check
  • keys(o) - Get keys (typed)
  • values(o) - Get values (typed)
  • entries(o) - Get entries (typed)
  • deepClone(obj) - Deep clone via JSON
  • deepMerge(target, source) - Recursive merge
  • isEqual(obj1, obj2) - Deep equality
  • get(obj, path, defaultValue) - Safe nested get
  • set(obj, path, value) - Safe nested set
  • has(obj, path) - Check nested property
  • invert(obj) - Swap keys and values
  • mapValues(obj, fn) - Transform values
  • mapKeys(obj, fn) - Transform keys
  • deepFreeze(obj) - Deep freeze
  • filterObject(obj, predicate) - Filter properties
  • unflatten(obj) - Convert dot-notation to nested

Date Utils

Comprehensive date utilities powered by native JS.

import {
  formatDate,
  formatRelativeTime,
  isToday,
  isYesterday,
  isFuture,
  addToDate,
  getDateDifference,
} from 'everyday-helper/utils';
import { DateFormats } from 'everyday-helper/constants';

// Format dates
const formatted = formatDate(new Date(), DateFormats.DD_MM_YYYY_WITH_DOT);
// '02.12.2025'

const relative = formatRelativeTime(new Date('2025-11-30'));
// '2 days ago'

// Date checks
if (isToday(someDate)) {
  console.log('Date is today!');
}

if (isYesterday(someDate)) {
  console.log('Date was yesterday');
}

// Date manipulation
const nextWeek = addToDate(new Date(), 7, 'day');
const lastMonth = subtractFromDate(new Date(), 1, 'month');

// Date comparison
const daysDiff = getDateDifference(date1, date2, 'day');
const age = getAge('1990-01-01'); // Age in years

Available functions:

  • formatDate(date, format) - Format date
  • formatRelativeTime(date, baseDate?) - Relative time string
  • isValidDate(date) - Validate date
  • isPast/isFuture(date) - Check if past/future
  • isToday/isYesterday/isTomorrow(date) - Day checks
  • isSameDay(date1, date2) - Compare days
  • isBetweenDates(date, start, end) - Range check
  • getDateDifference(date1, date2, unit) - Calculate difference
  • addToDate/subtractFromDate(date, amount, unit) - Manipulate dates
  • startOf/endOf(date, unit) - Get start/end of period
  • formatDateRange(start, end, format) - Format range
  • getAge(birthdate) - Calculate age
  • parseDate(dateString, format) - Parse with format
  • toISOString(date) - Convert to ISO string
  • toUnixTimestamp(date) - Convert to Unix timestamp
  • now() - Current date/time
  • compareDates(date1, date2) - Compare dates

Function Utils

Higher-order functions and function utilities.

import { debounce, throttle, memoize, once, retry } from 'everyday-helper/utils';

// Debounce function calls
const debouncedSearch = debounce((query) => {
  fetchResults(query);
}, 500);

// Throttle function calls
const throttledScroll = throttle(() => {
  updateScrollPosition();
}, 100);

// Memoize expensive calculations
const expensiveCalc = memoize((a, b) => {
  // Complex calculation
  return result;
});

// Run function only once
const initialize = once(() => {
  console.log('Initialized!');
});

// Retry failed async operations
const fetchData = retry(
  async () => {
    const response = await fetch('/api/data');
    if (!response.ok) throw new Error('Failed');
    return response.json();
  },
  3,
  1000,
); // 3 retries, 1s delay

Available functions:

  • noop() - No-op function
  • compose(...fns) - Function composition
  • debounce(fn, wait) - Debounce with cancel
  • throttle(fn, wait) - Throttle with cancel
  • memoize(fn, resolver?) - Memoization
  • once(fn) - Call once
  • delay(fn, wait, ...args) - Delayed execution
  • retry(fn, retries, delayMs) - Retry async function
  • curry(fn) - Curry function
  • flip(fn) - Flip arguments
  • partial(fn, ...partials) - Partial application
  • negate(predicate) - Negate predicate
  • safeCall(fn, ...args) - Safe function call
  • tryCatch(fn) - Sync try-catch wrapper
  • tryCatchAsync(fn) - Async try-catch wrapper
  • rateLimit(fn, minDelay) - Rate limiting
  • identity(value) - Identity function
  • constant(value) - Constant function
  • firstSeveral(arr, n) - First n elements
  • lastSeveral(arr, n) - Last n elements

Common Utils

General-purpose utility functions.

import { isEmpty, isNotEmpty, isNulOrUndefined, getImageUrl } from 'everyday-helper/utils';

// Check empty values
if (isEmpty(value)) {
  // Handles null, undefined, '', [], {}
}

if (isNotEmpty(value)) {
  // Value is not empty
}

// Null/undefined checks
if (isNulOrUndefined(value)) {
  // value is null or undefined
}

// Generate image URLs
const imageUrl = getImageUrl(fileId, 'https://api.example.com');
// 'https://api.example.com/fs/v1/files/123/download'

Convert Utils

File and data conversion utilities.

import {
  convertFileToBase64,
  convertBase64ToFile,
  extractBase64FromDataUrl,
  fileToArrayBuffer,
} from 'everyday-helper/utils';

// File to Base64
const base64 = await convertFileToBase64(file);
// 'data:image/png;base64,iVBORw0KG...'

// Base64 to File
const file = convertBase64ToFile(base64String, 'image.png', 'image/png');

// Extract Base64 from data URL
const pureBase64 = extractBase64FromDataUrl(dataUrl);

// File to ArrayBuffer
const buffer = await fileToArrayBuffer(file);

API Utils

API and HTTP-related utilities.

import { getEndpoint, generateQuery, isLoggedIn } from 'everyday-helper/utils';

// Get role-based endpoints
const endpoint = getEndpoint('admin', 'users', sharedFeatures);

// Generate query strings
const query = generateQuery({
  page: 1,
  search: 'john',
  filters: ['active', 'verified'],
  empty: '',
});
// 'page=1&search=john&filters=active&filters=verified'

// Check login status
if (isLoggedIn('access_token')) {
  // User is logged in
}

Phone Utils

Azerbaijan phone number utilities.

import {
  hasAzerbaijanCountryCode,
  withAzerbaijanCountryCode,
  normalizePhone,
} from 'everyday-helper/utils';

// Check for country code
const hascode = hasAzerbaijanCountryCode('0501234567'); // false

// Add country code
const phone = withAzerbaijanCountryCode('501234567');
// '+994501234567'

// Normalize phone number
const normalized = normalizePhone('0501234567');
// '+994501234567'

Animation Utils

CSS animation helper utilities.

import { animate, fadeIn, slideInUp, bounceIn } from 'everyday-helper/utils';

function AnimatedComponent() {
  return (
    <>
      <div {...fadeIn(0)}>Fades in first</div>
      <div {...slideInUp(1)}>Slides in second</div>
      <div {...bounceIn(2)}>Bounces in third</div>

      {/* Custom animation */}
      <div
        {...animate({
          type: 'fade-in',
          order: 3,
          delay: 0.5,
          className: 'extra-class',
        })}
      >
        Custom timing
      </div>
    </>
  );
}

Note: Import animations CSS once in your app:

import 'hh-toolkit/animations.css';

Available animations:

  • fadeIn(order?, className?, style?)
  • slideInUp(order?, className?, style?)
  • slideInDown(order?, className?, style?)
  • slideInLeft(order?, className?, style?)
  • slideInRight(order?, className?, style?)
  • scaleIn(order?, className?, style?)
  • bounceIn(order?, className?, style?)

Constants

DateFormats

Predefined date format strings for use with date utilities.

import { DateFormats } from 'everyday-helper/constants';

DateFormats.MMMM_DD_YYYY; // "MMMM DD, YYYY"
DateFormats.DD_MM_YYYY_WITH_DOT; // "DD.MM.YYYY"
DateFormats.DD_MM_YYYY_WITH_SLASH; // "DD/MM/YYYY"
DateFormats.YYYY_MM_DD_WITH_HYPEN; // "YYYY-MM-DD"
DateFormats.DD_MM_YYYY_WITH_HYPHEN; // "DD-MM-YYYY"
DateFormats.DD_MM_YYYY_HH_mm; // "DD/MM/YYYY HH:mm"
DateFormats.DD_MMM_YYYY_WITH_SPACE; // "DD MMM YYYY"

EventTypes

Comprehensive enum of DOM event types.

import { EventTypes } from 'everyday-helper/constants';

// Mouse events
EventTypes.CLICK;
EventTypes.MOUSE_MOVE;
EventTypes.MOUSE_ENTER;

// Keyboard events
EventTypes.KEY_DOWN;
EventTypes.ESCAPE;
EventTypes.ARROW_LEFT;

// Form events
EventTypes.SUBMIT;
EventTypes.CHANGE;
EventTypes.FOCUS;

// Window events
EventTypes.RESIZE;
EventTypes.SCROLL;
EventTypes.LOAD;

// And many more...

SortOrders

Sort order constants.

import { SortOrders } from 'everyday-helper/constants';

SortOrders.ASC; // 'asc'
SortOrders.DESC; // 'desc'

Import Paths

You can import from specific paths for better tree-shaking:

// Import all from main entry
import { useDebounce, formatDate, cn } from 'everyday-helper';

// Or import from specific modules
import { useDebounce } from 'everyday-helper/hooks';
import { formatDate } from 'everyday-helper/utils';
import { cn } from 'everyday-helper/lib';
import { DateFormats } from 'everyday-helper/constants';

TypeScript Support

This package is written in TypeScript and includes full type definitions. You'll get autocomplete and type checking out of the box.

import { formatDate, pick } from 'everyday-helper';

// Types are inferred automatically
const date = formatDate(new Date()); // string | undefined
const user = pick({ name: 'John', age: 30 }, ['name']); // { name: string }

Examples

Building a Search Component

import { useDebounce } from 'everyday-helper/hooks';
import { isEmpty } from 'everyday-helper/utils';
import { useState, useEffect } from 'react';

function SearchBar() {
  const [query, setQuery] = useState('');
  const [results, setResults] = useState([]);
  const debouncedQuery = useDebounce(query, 300);

  useEffect(() => {
    if (isEmpty(debouncedQuery)) {
      setResults([]);
      return;
    }

    fetch(`/api/search?q=${debouncedQuery}`)
      .then((res) => res.json())
      .then(setResults);
  }, [debouncedQuery]);

  return (
    <div>
      <input value={query} onChange={(e) => setQuery(e.target.value)} placeholder="Search..." />
      <ul>
        {results.map((item) => (
          <li key={item.id}>{item.name}</li>
        ))}
      </ul>
    </div>
  );
}

Modal with Outside Click & Escape Key

import { useOutsideClick, useEscapeKey, useScrollLock } from 'everyday-helper/hooks';
import { useRef } from 'react';

function Modal({ isOpen, onClose, children }) {
  const modalRef = useRef(null);

  useScrollLock({ isLocked: isOpen });
  useOutsideClick(modalRef, onClose);
  useEscapeKey({ onEscape: onClose, enabled: isOpen });

  if (!isOpen) return null;

  return (
    <div className="modal-overlay">
      <div ref={modalRef} className="modal-content">
        {children}
      </div>
    </div>
  );
}

Data Table with Sorting

import { sortBy, groupBy } from 'everyday-helper/utils';
import { SortOrders } from 'everyday-helper/constants';
import { useState } from 'react';

function DataTable({ data }) {
  const [sortKey, setSortKey] = useState('name');
  const [sortOrder, setSortOrder] = useState(SortOrders.ASC);

  const sortedData = sortBy(data, sortKey, sortOrder);
  const groupedByRole = groupBy(sortedData, 'role');

  return (
    <table>
      <thead>
        <tr>
          <th onClick={() => setSortKey('name')}>Name</th>
          <th onClick={() => setSortKey('age')}>Age</th>
          <th onClick={() => setSortKey('role')}>Role</th>
        </tr>
      </thead>
      <tbody>
        {sortedData.map((row) => (
          <tr key={row.id}>
            <td>{row.name}</td>
            <td>{row.age}</td>
            <td>{row.role}</td>
          </tr>
        ))}
      </tbody>
    </table>
  );
}