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

@clidey/ux

v0.41.0

Published

<p align="center"> <img src="./docs/logo/logo.png" alt="Clidey UX" height="72" /> </p>

Readme


Why Clidey UX?

Building a consistent, accessible UI from scratch takes weeks. Clidey UX gives you a complete set of polished components so you can focus on your product, not your design system.

  • Accessible by default — every component is built on Radix UI primitives. Keyboard navigation, focus management, and ARIA attributes are handled for you.
  • Dark mode included — wrap your app with ThemeProvider and all components adapt automatically. System preference detection and localStorage persistence built in.
  • Fully typed — complete TypeScript definitions with strict mode. Autocomplete for every prop, variant, and event handler.
  • Composable API — sub-component patterns give you full control over layout and markup without fighting against an opinionated structure.
  • Tailwind CSS v4 — styled with utility classes you already know. Override anything with className.
  • Zero configuration — one import, one stylesheet, done.

Installation

npm install @clidey/ux
# or
pnpm add @clidey/ux
# or
yarn add @clidey/ux

Import the stylesheet once at your app entry point:

// main.tsx / _app.tsx
import '@clidey/ux/styles.css';

Wrap with ThemeProvider to enable dark mode:

import { ThemeProvider } from '@clidey/ux';

export default function App() {
  return (
    <ThemeProvider defaultTheme="system">
      {/* your app */}
    </ThemeProvider>
  );
}

That's it. No extra configuration, no Tailwind setup required in your project.


Quick start

import {
  Button,
  Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter,
  Badge,
  Input,
  Label,
} from '@clidey/ux';
import '@clidey/ux/styles.css';

export default function Example() {
  return (
    <Card className="max-w-sm">
      <CardHeader>
        <CardTitle>Create account</CardTitle>
        <CardDescription>Get started in seconds. No credit card required.</CardDescription>
      </CardHeader>
      <CardContent className="space-y-3">
        <div className="space-y-1">
          <Label htmlFor="email">Email</Label>
          <Input id="email" type="email" placeholder="[email protected]" />
        </div>
        <div className="space-y-1">
          <Label htmlFor="password">Password</Label>
          <Input id="password" type="password" showPasswordToggle />
        </div>
      </CardContent>
      <CardFooter className="flex items-center justify-between">
        <Badge variant="outline">Free plan</Badge>
        <Button>Create account</Button>
      </CardFooter>
    </Card>
  );
}

Components

Actions

| Component | Description | | --- | --- | | Button | 6 variants (default, destructive, outline, secondary, ghost, link) · 4 sizes | | ButtonGroup | Connected button strip for toolbars and segmented controls |

Inputs

| Component | Description | | --- | --- | | Input | Text field with optional password toggle | | TextArea | Multi-line text input | | SearchInput | Text field with built-in search icon | | Checkbox | Accessible checkbox with indeterminate state | | Switch | Toggle for boolean settings | | Select | Composable dropdown selector | | SearchSelect | Dropdown with search filtering and icon support | | Label | Accessible form label |

Display

| Component | Description | | --- | --- | | Badge | Status and category labels · 4 variants | | Card | Container with header, content, footer, and action slots | | Alert | Inline feedback messages · default and destructive | | Spinner | Animated loader · 5 color variants · 3 sizes | | Skeleton | Pulsing placeholder for loading states | | Progress | Linear progress bar | | EmptyState | Placeholder for empty lists and zero-state screens | | Separator | Horizontal or vertical divider |

Navigation

| Component | Description | | --- | --- | | Tabs | Tab panels for switching between sections | | Breadcrumb | Hierarchical path with ellipsis support | | Pagination | Previous / next and numbered page controls | | Sidebar | Full sidebar with collapsible menus, submenus, mobile support |

Overlays

| Component | Description | | --- | --- | | Dialog | Modal with focus trap and scroll lock | | AlertDialog | Blocking confirmation for destructive actions | | Drawer | Slide-in panel from any edge (powered by Vaul) | | Sheet | Side panel overlay (powered by Radix Dialog) | | Tooltip | Hover label with configurable delay and position | | Popover | Click-anchored floating panel |

Menus

| Component | Description | | --- | --- | | DropdownMenu | Trigger menu with checkboxes, radio groups, and sub-menus | | ContextMenu | Right-click menu with the same rich item types | | Command | Fuzzy-search command palette (⌘K) powered by cmdk |

Layout

| Component | Description | | --- | --- | | Accordion | Collapsible sections with animated expand/collapse | | ResizablePanelGroup | Drag-to-resize split views | | ScrollArea | Custom scrollbar with styled track and thumb | | StackList | Key-value metadata list with separators |

Data & Visualization

| Component | Description | | --- | --- | | Table | Full table with virtualization for large datasets and JSON preview | | Chart | Recharts wrapper with theme-aware tooltips and legend | | Tree | Hierarchical tree / file explorer with expand and selection |

Utilities

| Component | Description | | --- | --- | | Icon | SVG wrapper with consistent sizing | | Toaster | Toast notifications powered by Sonner |

Theme

| Component / Hook | Description | | --- | --- | | ThemeProvider | Context provider for light / dark / system theme | | useTheme | Hook to read and set the active theme | | ModeToggle | Ready-made dropdown to switch themes |


Usage examples

Confirmation dialog

import {
  AlertDialog, AlertDialogTrigger, AlertDialogContent,
  AlertDialogHeader, AlertDialogTitle, AlertDialogDescription,
  AlertDialogFooter, AlertDialogCancel, AlertDialogAction,
  Button,
} from '@clidey/ux';

<AlertDialog>
  <AlertDialogTrigger asChild>
    <Button variant="destructive">Delete account</Button>
  </AlertDialogTrigger>
  <AlertDialogContent>
    <AlertDialogHeader>
      <AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
      <AlertDialogDescription>
        This action cannot be undone. Your data will be permanently deleted.
      </AlertDialogDescription>
    </AlertDialogHeader>
    <AlertDialogFooter>
      <AlertDialogCancel>Cancel</AlertDialogCancel>
      <AlertDialogAction>Delete account</AlertDialogAction>
    </AlertDialogFooter>
  </AlertDialogContent>
</AlertDialog>

Toast notifications

import { Toaster, toast } from '@clidey/ux';

// In your root layout
<Toaster />

// Anywhere in your app
toast.success('Saved successfully!');
toast.error('Something went wrong.');
toast.promise(saveData(), {
  loading: 'Saving...',
  success: 'Done!',
  error: 'Failed to save.',
});

Command palette (⌘K)

import {
  CommandDialog, CommandInput, CommandList,
  CommandEmpty, CommandGroup, CommandItem,
} from '@clidey/ux';

<CommandDialog open={open} onOpenChange={setOpen}>
  <CommandInput placeholder="Search commands..." />
  <CommandList>
    <CommandEmpty>No results found.</CommandEmpty>
    <CommandGroup heading="Navigation">
      <CommandItem onSelect={() => navigate('/dashboard')}>Dashboard</CommandItem>
      <CommandItem onSelect={() => navigate('/settings')}>Settings</CommandItem>
    </CommandGroup>
  </CommandList>
</CommandDialog>

Large dataset table with virtualization

import {
  TableProvider, Table, TableHeader, TableHeadRow,
  TableHead, VirtualizedTableBody, TableRow, TableCell,
} from '@clidey/ux';

<TableProvider columnCount={3}>
  <Table>
    <TableHeader>
      <TableHeadRow>
        <TableHead>ID</TableHead>
        <TableHead>Name</TableHead>
        <TableHead>Status</TableHead>
      </TableHeadRow>
    </TableHeader>
    <VirtualizedTableBody rowCount={10000} rowHeight={48} height={400}>
      {({ index, style }) => (
        <TableRow style={style}>
          <TableCell>{rows[index].id}</TableCell>
          <TableCell>{rows[index].name}</TableCell>
          <TableCell>{rows[index].status}</TableCell>
        </TableRow>
      )}
    </VirtualizedTableBody>
  </Table>
</TableProvider>

Theming

All visual tokens are exposed as CSS custom properties. Override them in your own stylesheet after importing @clidey/ux/styles.css:

:root {
  --primary: 250 84% 54%;          /* your brand color */
  --radius: 0.375rem;              /* border radius */
}

Dark mode is automatic — ThemeProvider applies a dark class to <html> and all components respond to it via Tailwind's dark: modifier.


Next.js

// app/providers.tsx
'use client';
import { ThemeProvider } from '@clidey/ux';

export function Providers({ children }: { children: React.ReactNode }) {
  return <ThemeProvider defaultTheme="system">{children}</ThemeProvider>;
}

// app/layout.tsx
import '@clidey/ux/styles.css';
import { Providers } from './providers';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en" suppressHydrationWarning>
      <body>
        <Providers>{children}</Providers>
      </body>
    </html>
  );
}

Peer dependencies

| Package | Version | | --- | --- | | react | >= 18.3.0 | | react-dom | >= 18.3.0 |

All other dependencies (Radix UI, Lucide, Recharts, Sonner, Vaul, cmdk) are bundled — no extra installs needed.


Contributing

Contributions, bug reports, and feature requests are welcome. Please open an issue or pull request on GitHub.

License

MIT — free to use in personal and commercial projects.