JSPM

@ninna-ui/utils

0.6.0
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 40
  • Score
    100M100P100Q72824F
  • License MIT

Shared utility functions for Ninna UI - cn (class merging), composeRefs, createContext, keyboard constants, and SSR helpers.

Package Exports

  • @ninna-ui/utils
  • @ninna-ui/utils/package.json

Readme

@ninna-ui/utils

Shared utility toolkit for the Ninna UI ecosystem - intelligent Tailwind class merging, ref composition, type-safe React context, keyboard constants, and SSR-safe helpers. Zero side effects. Tree-shakeable.

License: MIT

The shared utility layer powering every Ninna UI component package. Core utilities (cn, KEYS, canUseDOM) are pure functions with no React dependency - they work in any JavaScript environment. React-aware utilities (createContext, composeRefs) use React as an optional peer dependency.

Installation

pnpm add @ninna-ui/utils

Exports

cn(...inputs) - Class Name Merger

Combines Tailwind CSS classes with intelligent conflict resolution. Built on clsx + tailwind-merge.

import { cn } from '@ninna-ui/utils';

cn('px-4 py-2', 'px-6');              // "py-2 px-6" - px-4 overridden
cn('text-red-500', false && 'hidden'); // "text-red-500"
cn('rounded-md', undefined, 'p-4');    // "rounded-md p-4"

composeRefs(...refs) - Ref Composition

Combines multiple React refs into a single ref callback. Essential for forwardRef components that also use internal refs.

import { composeRefs } from '@ninna-ui/utils';

const Component = forwardRef((props, forwardedRef) => {
  const internalRef = useRef(null);
  return <div ref={composeRefs(forwardedRef, internalRef)} />;
});

composeEventHandlers(external, internal) - Event Handler Composition

Chains event handlers so both external (user-provided) and internal handlers run. Respects event.preventDefault().

import { composeEventHandlers } from '@ninna-ui/utils';

<button onClick={composeEventHandlers(props.onClick, handleInternalClick)} />

createContext(name) - Type-Safe Context

Creates a React context with a required provider. Throws a helpful error if consumed outside its provider.

import { createContext } from '@ninna-ui/utils';

const [FormProvider, useFormContext] = createContext<FormContextValue>('FormControl');

KEYS - Keyboard Constants

Standard keyboard key constants for accessible event handling:

import { KEYS } from '@ninna-ui/utils';

KEYS.ENTER      // "Enter"
KEYS.ESCAPE     // "Escape"
KEYS.SPACE      // " "
KEYS.ARROW_UP   // "ArrowUp"
KEYS.ARROW_DOWN // "ArrowDown"
KEYS.TAB        // "Tab"

canUseDOM / getOwnerWindow - SSR Safety

Runtime checks for safe DOM access in server-side rendering contexts:

import { canUseDOM, getOwnerWindow } from '@ninna-ui/utils';

if (canUseDOM) {
  // Safe to access window, document
}

const win = getOwnerWindow(element); // Get the owner window of a DOM element

Architecture Rules

  • React is optional - cn, KEYS, canUseDOM are pure; createContext and composeRefs require React
  • No DOM APIs - Must work in SSR contexts (canUseDOM is a check, not a usage)
  • No @ninna-ui/* imports - This is a leaf dependency
  • No side effects - All functions are pure

License

MIT