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

@cdowd/ui

v0.3.4

Published

A comprehensive UI component library for Keee AI applications

Readme

@keee-ai/ui

A modern, accessible, and customizable React component library built with TypeScript, Tailwind CSS, and Radix UI.

🚀 Features

  • 🎨 Modern Design: Built with Tailwind CSS and custom design tokens
  • ♿ Accessible: Based on Radix UI primitives for excellent accessibility
  • 📱 Responsive: Mobile-first design approach
  • 🎯 TypeScript: Full TypeScript support with comprehensive type definitions
  • 🔧 Customizable: Easy to customize with CSS variables and Tailwind classes
  • 📚 Storybook: Interactive documentation and component playground
  • ⚡ Fast: Optimized bundle size with tree-shaking support

📦 Installation

npm install @keee-ai/ui
# or
yarn add @keee-ai/ui
# or
pnpm add @keee-ai/ui

Note: This package is published to GitHub Packages. You may need to configure npm to use the GitHub registry:

# Add this to your .npmrc file
@keee-ai:registry=https://npm.pkg.github.com

🎯 Quick Start

1. Install Dependencies

The UI package has the following peer dependencies that need to be installed in your project:

npm install react react-dom
npm install @radix-ui/react-dialog @radix-ui/react-dropdown-menu @radix-ui/react-select @radix-ui/react-tabs @radix-ui/react-tooltip @radix-ui/react-popover @radix-ui/react-checkbox @radix-ui/react-switch @radix-ui/react-radio-group @radix-ui/react-sheet
npm install lucide-react
npm install class-variance-authority clsx tailwind-merge
npm install react-hook-form @hookform/resolvers zod
npm install @tanstack/react-table
npm install cmdk

2. Set up Tailwind CSS

Add the UI package's CSS to your main CSS file:

@import '@keee-ai/ui/dist/style.css';

3. Configure Tailwind

Update your tailwind.config.js to include the UI package:

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    './src/**/*.{js,ts,jsx,tsx}',
    './node_modules/@keee-ai/ui/dist/**/*.{js,ts,jsx,tsx}',
  ],
  theme: {
    extend: {
      colors: {
        border: 'hsl(var(--border))',
        input: 'hsl(var(--input))',
        ring: 'hsl(var(--ring))',
        background: 'hsl(var(--background))',
        foreground: 'hsl(var(--foreground))',
        primary: {
          DEFAULT: 'hsl(var(--primary))',
          foreground: 'hsl(var(--primary-foreground))',
        },
        secondary: {
          DEFAULT: 'hsl(var(--secondary))',
          foreground: 'hsl(var(--secondary-foreground))',
        },
        destructive: {
          DEFAULT: 'hsl(var(--destructive))',
          foreground: 'hsl(var(--destructive-foreground))',
        },
        muted: {
          DEFAULT: 'hsl(var(--muted))',
          foreground: 'hsl(var(--muted-foreground))',
        },
        accent: {
          DEFAULT: 'hsl(var(--accent))',
          foreground: 'hsl(var(--accent-foreground))',
        },
        popover: {
          DEFAULT: 'hsl(var(--popover))',
          foreground: 'hsl(var(--popover-foreground))',
        },
        card: {
          DEFAULT: 'hsl(var(--card))',
          foreground: 'hsl(var(--card-foreground))',
        },
      },
      borderRadius: {
        lg: 'var(--radius)',
        md: 'calc(var(--radius) - 2px)',
        sm: 'calc(var(--radius) - 4px)',
      },
    },
  },
  plugins: [],
};

4. Use Components

import { Button, Card, Input } from '@keee-ai/ui';

function App() {
  return (
    <div className='p-4'>
      <Card className='w-full max-w-md'>
        <CardHeader>
          <CardTitle>Welcome</CardTitle>
          <CardDescription>Get started with our UI library</CardDescription>
        </CardHeader>
        <CardContent className='space-y-4'>
          <Input placeholder='Enter your name' />
          <Button>Submit</Button>
        </CardContent>
      </Card>
    </div>
  );
}

🧩 Components

Basic Components

  • Button - Versatile button component with multiple variants
  • Input - Form input with validation states
  • Label - Accessible form labels
  • Textarea - Multi-line text input
  • Checkbox - Accessible checkbox component
  • Switch - Toggle switch component
  • RadioGroup - Radio button group
  • Select - Dropdown select component
  • Badge - Status and label badges
  • Separator - Visual divider component
  • Skeleton - Loading placeholder component

Layout Components

  • Card - Container with header, content, and footer
  • Dialog - Modal dialog component
  • Sheet - Slide-out panel component
  • Popover - Floating content container
  • Tooltip - Hover information display
  • Tabs - Tabbed interface component

Data Display

  • Table - Basic table component
  • DataTable - Advanced table with sorting, filtering, and pagination
  • Timeline - Chronological event display

Form Components

  • Form - Form wrapper with validation
  • EditableFieldGroup - Inline editing interface
  • ModalForm - Form in a modal dialog

Navigation

  • Sidebar - Collapsible sidebar navigation
  • SidebarNav - Navigation within sidebar

📖 Component Examples

Button

import { Button } from '@keee-ai/ui'

// Different variants
<Button variant="default">Default</Button>
<Button variant="destructive">Delete</Button>
<Button variant="outline">Outline</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="link">Link</Button>

// Different sizes
<Button size="default">Default</Button>
<Button size="sm">Small</Button>
<Button size="lg">Large</Button>
<Button size="icon">🚀</Button>

DataTable

import { DataTable } from '@keee-ai/ui';
import type { TableColumn } from '@keee-ai/ui';

interface User {
  id: string;
  name: string;
  email: string;
  role: string;
}

const columns: TableColumn<User>[] = [
  {
    id: 'name',
    header: 'Name',
    accessorKey: 'name',
    sortable: true,
  },
  {
    id: 'email',
    header: 'Email',
    accessorKey: 'email',
    sortable: true,
  },
  {
    id: 'role',
    header: 'Role',
    accessorKey: 'role',
  },
];

function UserTable() {
  const [pageIndex, setPageIndex] = useState(0);
  const [pageSize, setPageSize] = useState(10);

  return (
    <DataTable
      columns={columns}
      data={users}
      pageCount={Math.ceil(users.length / pageSize)}
      pageSize={pageSize}
      pageIndex={pageIndex}
      onPaginationChange={(newPageIndex, newPageSize) => {
        setPageIndex(newPageIndex);
        setPageSize(newPageSize);
      }}
      enableSorting
      enableFiltering
      enableSelection
    />
  );
}

EditableFieldGroup

import { EditableFieldGroup, EditableField } from '@keee-ai/ui';

function UserProfile() {
  const [isEditing, setIsEditing] = useState(false);

  return (
    <EditableFieldGroup
      isEditing={isEditing}
      onEdit={() => setIsEditing(true)}
      onSave={() => setIsEditing(false)}
      onCancel={() => setIsEditing(false)}
    >
      <EditableField
        label='Name'
        value='John Doe'
        onChange={(value) => console.log('Name changed:', value)}
      />
      <EditableField
        label='Email'
        value='[email protected]'
        onChange={(value) => console.log('Email changed:', value)}
      />
    </EditableFieldGroup>
  );
}

🎨 Theming

The UI package uses CSS custom properties for theming. You can customize the appearance by overriding these variables:

:root {
  --background: 0 0% 100%;
  --foreground: 222.2 84% 4.9%;
  --primary: 222.2 47.4% 11.2%;
  --primary-foreground: 210 40% 98%;
  --secondary: 210 40% 96%;
  --secondary-foreground: 222.2 84% 4.9%;
  --muted: 210 40% 96%;
  --muted-foreground: 215.4 16.3% 46.9%;
  --accent: 210 40% 96%;
  --accent-foreground: 222.2 84% 4.9%;
  --destructive: 0 84.2% 60.2%;
  --destructive-foreground: 210 40% 98%;
  --border: 214.3 31.8% 91.4%;
  --input: 214.3 31.8% 91.4%;
  --ring: 222.2 84% 4.9%;
  --radius: 0.5rem;
}

.dark {
  --background: 222.2 84% 4.9%;
  --foreground: 210 40% 98%;
  --primary: 210 40% 98%;
  --primary-foreground: 222.2 47.4% 11.2%;
  --secondary: 217.2 32.6% 17.5%;
  --secondary-foreground: 210 40% 98%;
  --muted: 217.2 32.6% 17.5%;
  --muted-foreground: 215 20.2% 65.1%;
  --accent: 217.2 32.6% 17.5%;
  --accent-foreground: 210 40% 98%;
  --destructive: 0 62.8% 30.6%;
  --destructive-foreground: 210 40% 98%;
  --border: 217.2 32.6% 17.5%;
  --input: 217.2 32.6% 17.5%;
  --ring: 212.7 26.8% 83.9%;
}

🔧 Development

Prerequisites

  • Node.js 18+
  • pnpm (recommended) or npm

Setup

  1. Clone the repository
  2. Install dependencies: pnpm install
  3. Start Storybook: pnpm storybook
  4. Build the package: pnpm build

Available Scripts

  • pnpm dev - Start development mode
  • pnpm build - Build the package
  • pnpm storybook - Start Storybook
  • pnpm build-storybook - Build Storybook for production
  • pnpm type-check - Run TypeScript type checking
  • pnpm lint - Run ESLint
  • pnpm clean - Clean build artifacts

Publishing

This package is published to GitHub Packages for the Keee AI organization. To publish a new version:

Prerequisites

  1. GitHub Authentication: You must have a GitHub Personal Access Token with write:packages permission
  2. Organization Access: You need publish permissions for the @keee-ai scope
  3. Repository Access: You need access to the keee-ai/keee-portal-v2 repository

Publishing Commands

For bug fixes and small changes:

pnpm publish:patch
# This bumps version from 0.1.0 → 0.1.1

For new features (backward compatible):

pnpm publish:minor
# This bumps version from 0.1.0 → 0.2.0

For breaking changes:

pnpm publish:major
# This bumps version from 0.1.0 → 1.0.0

Manual publishing (if you've already bumped the version):

pnpm release

What happens during publishing:

  1. Version bump: Automatically increments the version number
  2. Build: Compiles TypeScript and bundles CSS
  3. Type check: Ensures no TypeScript errors
  4. Changelog update: Adds the new version to CHANGELOG.md
  5. Publish: Uploads to GitHub Packages

After publishing:

  • The new version will be available to other repos in your organization
  • Update other projects to use the new version: pnpm update @keee-ai/ui
  • The changelog will be updated with the new version and date
  • The package will be visible at: https://github.com/keee-ai/keee-portal-v2/packages

Adding New Components

  1. Create the component in `