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

@ui-construction-library/core

v0.7.0

Published

Primary React UI component library — atoms, molecules, organisms and templates for product surfaces.

Downloads

1,004

Readme

@ui-construction-library/core

Primary public entrypoint for the UI Construction Library. Contains base UI components, provider/theme glue, and public hooks for almost all consumer scenarios.

When to use

Start here. This package covers ~80% of UI needs — atoms, molecules, organisms, and templates. Add extension packages only when you need motion, drag-and-drop, or form adapters.

Installation

pnpm add @ui-construction-library/core

Peer dependencies

{
  "react": ">=18.0.0",
  "react-dom": ">=18.0.0"
}

Minimal example

import { ThemeProvider, Button, Input, Modal } from '@ui-construction-library/core';
import '@ui-construction-library/core/styles.css';
import { useState } from 'react';

export function App() {
  const [open, setOpen] = useState(false);

  return (
    <ThemeProvider>
      <Input label="Project name" placeholder="Aurora Dashboard" />
      <Button onClick={() => setOpen(true)}>Open settings</Button>

      <Modal open={open} onOpenChange={setOpen}>
        <Modal.Content size="md" title="Settings">
          <Modal.Body>Configure your project.</Modal.Body>
          <Modal.Footer>
            <Modal.Close asChild>
              <Button variant="outline">Cancel</Button>
            </Modal.Close>
            <Button>Save</Button>
          </Modal.Footer>
        </Modal.Content>
      </Modal>
    </ThemeProvider>
  );
}

Integration with other packages

# Icons
pnpm add @ui-construction-library/icons

# Form adapters
pnpm add @ui-construction-library/react-hook-form react-hook-form

# Drag and drop
pnpm add @ui-construction-library/dnd

# Animation
pnpm add @ui-construction-library/motion

Styling and theme

Import the bundled stylesheet once in your app entry point:

import '@ui-construction-library/core/styles.css';
// or
import '@ui-construction-library/core/styles';

Wrap your app with ThemeProvider to enable light/dark mode and token overrides:

import { ThemeProvider } from '@ui-construction-library/core';

<ThemeProvider theme="light">{/* app */}</ThemeProvider>

Compatibility

  • React 18 and 19
  • TypeScript 5.x and 6.x
  • Vite 5+, Next.js 15 (App Router), Rollup 4+, webpack 5

Public API

All exports are available from the package root:

import { Button, Input, Modal, DataTable, Tabs, ... } from '@ui-construction-library/core';

Subpath exports:

  • @ui-construction-library/core/styles.css — bundled stylesheet

Do not import from dist/* or src/* paths.

Components

| Component | Category | Description | |-----------|----------|-------------| | Button | Atom | Styled button with variants (default, outline, ghost, danger) | | Input | Atom | Text input with label, error, and hint support | | FloatingLabelInput | Atom | Text input with animated floating label | | Stack | Atom | Flex-based vertical or horizontal layout with gap control | | Cluster | Atom | Inline-flex horizontal layout for tags, button groups, icon lists | | Modal | Molecule | Accessible dialog with header, body, footer, and close handling | | ToastProvider / useToast | Molecule | Context-based toast notification system with auto-dismiss | | CoachMark | Molecule | Dismissible onboarding card with localStorage persistence | | PageTip | Molecule | Compact dismissible inline tip banner | | Tabs | Organism | Tab navigation with content panel switching | | DataTable | Organism | Sortable, filterable data table with pagination | | KpiCard / KpiGrid | Organism | Dashboard metric cards with semantic variants and grid layout | | ErrorBoundary | Organism | Class-based error boundary with chunk-load detection and reset |

ToastProvider + useToast

Context-based toast notification system. Wrap your app with ToastProvider, then call useToast().push() anywhere in the tree to show a toast.

import { ToastProvider, useToast } from '@ui-construction-library/core';

function App() {
  return (
    <ToastProvider maxToasts={5} position="bottom-right">
      <MainContent />
    </ToastProvider>
  );
}

function MainContent() {
  const toast = useToast();

  const handleSave = () => {
    toast.push({ message: 'Saved successfully', variant: 'success' });
  };

  return <button onClick={handleSave}>Save</button>;
}

ToastProvider props: | Prop | Type | Default | Description | |------|------|---------|-------------| | children | ReactNode | — | App tree | | maxToasts | number | 5 | Max visible toasts at once | | position | 'bottom-right' \| 'bottom-left' \| 'top-right' \| 'top-left' | 'bottom-right' | Toast stack position |

useToast() return value: | Method | Signature | Description | |--------|-----------|-------------| | push | (msg: Omit<ToastMessage, 'id'>) => string | Add a toast; returns the toast id | | dismiss | (id: string) => void | Dismiss a specific toast | | dismissAll | () => void | Dismiss all visible toasts |

ToastMessage fields: | Field | Type | Default | Description | |-------|------|---------|-------------| | message | string | — | Toast text | | variant | 'default' \| 'success' \| 'warning' \| 'error' \| 'info' | 'default' | Visual intent | | duration | number | 3000 | Auto-dismiss ms. Set to 0 to keep open |


KpiCard + KpiGrid

Dashboard metric cards with semantic color variants. KpiCard renders a single KPI with label, value, optional subtext, and icon. KpiGrid arranges cards in a CSS Grid layout.

import { KpiCard, KpiGrid } from '@ui-construction-library/core';

<KpiGrid columns={3}>
  <KpiCard
    label="Active Users"
    value="24,831"
    subtext="+12% vs last week"
    variant="success"
  />
  <KpiCard
    label="Error Rate"
    value="0.8%"
    variant="error"
  />
  <KpiCard
    label="Avg Response"
    value="142ms"
    subtext="P95: 310ms"
    variant="warning"
  />
</KpiGrid>

KpiCard props: | Prop | Type | Default | Description | |------|------|---------|-------------| | label | string | — | Primary metric label | | value | string \| number | — | The metric value | | subtext | string | — | Sub-text below value (e.g., "vs last week") | | icon | ReactNode | — | Icon rendered above label | | variant | 'default' \| 'success' \| 'warning' \| 'error' | 'default' | Left border accent color | | selected | boolean | — | Selected/active visual state | | onClick | () => void | — | When set, renders as a <button> | | className | string | — | Additional class name |

KpiGrid props: | Prop | Type | Default | Description | |------|------|---------|-------------| | children | ReactNode | — | KpiCard children | | columns | number | auto-fill, min 16rem | Explicit column count | | className | string | — | Additional class name |


Stack + Cluster

Flex-based layout utilities. Stack arranges children vertically (default) or horizontally with consistent spacing. Cluster is an inline-flex horizontal layout that wraps, suited for tag groups and button bars.

import { Stack, Cluster } from '@ui-construction-library/core';

// Vertical stack
<Stack gap="1.5rem">
  <Section />
  <Section />
</Stack>

// Horizontal stack
<Stack direction="horizontal" gap="0.75rem" align="center">
  <Avatar />
  <UserName />
</Stack>

// Cluster for tags/badges
<Cluster gap="0.5rem">
  <Badge>React</Badge>
  <Badge>TypeScript</Badge>
  <Badge>Tailwind</Badge>
</Cluster>

Stack props: | Prop | Type | Default | Description | |------|------|---------|-------------| | children | ReactNode | — | Content to stack | | gap | string \| number | '1rem' | Spacing (number = rem) | | direction | 'vertical' \| 'horizontal' | 'vertical' | Flex direction | | align | CSSProperties['alignItems'] | — | Align items | | justify | CSSProperties['justifyContent'] | — | Justify content | | wrap | boolean | — | Enable wrap (horizontal only) | | className | string | — | Additional class name | | style | CSSProperties | — | Inline styles |

Cluster props: | Prop | Type | Default | Description | |------|------|---------|-------------| | children | ReactNode | — | Items to cluster | | gap | string \| number | '0.5rem' | Spacing (number = rem) | | align | CSSProperties['alignItems'] | 'center' | Align items | | justify | CSSProperties['justifyContent'] | — | Justify content | | className | string | — | Additional class name | | style | CSSProperties | — | Inline styles |


ErrorBoundary

Class-based React error boundary. Catches rendering errors in its subtree and displays a fallback UI. Detects ChunkLoadError (code-split chunk failures) and shows a "Reload page" button instead of "Try again".

import { ErrorBoundary } from '@ui-construction-library/core';

<ErrorBoundary
  onError={(error, errorInfo) => {
    reportToServer(error, errorInfo);
  }}
>
  <HeavyDashboard />
</ErrorBoundary>

Props: | Prop | Type | Default | Description | |------|------|---------|-------------| | children | ReactNode | — | Subtree to catch errors for | | fallback | ReactNode \| ((error, reset) => ReactNode) | Built-in UI | Custom fallback or render function | | onError | (error, errorInfo) => void | — | Called when an error is caught | | resetKey | string \| number | — | Changing this value resets the boundary |

The built-in fallback shows "Something went wrong" / "Failed to load module" with a reset or reload button. In development mode, error details and stack trace are shown in a collapsible section.


FloatingLabelInput

A text <input> with an animated label that starts inside the field and floats above it on focus or when a value is present.

import { FloatingLabelInput } from '@ui-construction-library/core';

<FloatingLabelInput
  label="Project name"
  value={name}
  onChange={(e) => setName(e.target.value)}
  error={validationError}
/>

<FloatingLabelInput
  label="Description"
  hint="Briefly describe your project"
/>

Props: | Prop | Type | Default | Description | |------|------|---------|-------------| | label | string | — | Floating label text | | error | string | — | Error message; shows input in error state | | hint | string | — | Hint text below input (hidden when error is set) |

Extends all native <input> attributes except placeholder.


CoachMark

A dismissible onboarding card. Once dismissed, the choice is persisted in localStorage so the card does not reappear on subsequent visits.

import { CoachMark } from '@ui-construction-library/core';

<CoachMark
  id="dashboard-onboarding"
  title="Welcome to your dashboard"
  dismissLabel="Got it"
>
  <p>Drag widgets to customize your view. Changes save automatically.</p>
</CoachMark>

Props: | Prop | Type | Default | Description | |------|------|---------|-------------| | id | string | — | Unique identifier for dismiss persistence | | children | ReactNode | — | Card content | | title | string | — | Title displayed above content | | dismissLabel | string | 'Got it' | Dismiss button label | | storageKey | string | 'ucl-coachmark' | localStorage key prefix | | onDismiss | (id: string) => void | — | Called when dismissed | | className | string | — | Additional class name |


PageTip

A compact dismissible inline tip banner. Similar persistence pattern to CoachMark but rendered as a horizontal bar with optional icon, content, and an × dismiss button.

import { PageTip } from '@ui-construction-library/core';

<PageTip id="export-tip">
  You can export your data as CSV or JSON from the Settings page.
</PageTip>

Props: | Prop | Type | Default | Description | |------|------|---------|-------------| | id | string | — | Unique identifier for dismiss persistence | | children | ReactNode | — | Tip content | | icon | ReactNode | — | Icon displayed before content | | storageKey | string | 'ucl-pagetip' | localStorage key prefix | | onDismiss | (id: string) => void | — | Called when dismissed | | className | string | — | Additional class name |

Troubleshooting

Styles not applying — make sure you import @ui-construction-library/core/styles.css before your own CSS.

ThemeProvider missing — wrap your app root with <ThemeProvider>. Without it, theme tokens will not resolve.

SSR / Next.js — use the 'use client' directive on any component that uses hooks or browser APIs. The ThemeProvider must be in a client component.