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

@elsapiens/ui

v0.1.19

Published

UI components for elSapiens SDK

Downloads

1,432

Readme

@elsapiens/ui

Comprehensive React UI component library for building modern interfaces.

Installation

npm install @elsapiens/ui @elsapiens/utils @elsapiens/styles
# or
pnpm add @elsapiens/ui @elsapiens/utils @elsapiens/styles

Features

  • 50+ production-ready React components
  • TypeScript support with full type definitions
  • Tailwind CSS styling with CSS variables
  • Form integration ready
  • Chart components powered by Recharts
  • Accessible and responsive

Quick Start

import { Button, Card, CardHeader, CardTitle, CardContent } from '@elsapiens/ui';
import '@elsapiens/styles';

function App() {
  return (
    <Card>
      <CardHeader>
        <CardTitle>Welcome</CardTitle>
      </CardHeader>
      <CardContent>
        <Button>Get Started</Button>
      </CardContent>
    </Card>
  );
}

Components

Form Components

Button

import { Button } from '@elsapiens/ui';

<Button>Default</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="outline">Outline</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="destructive">Destructive</Button>

<Button size="sm">Small</Button>
<Button size="lg">Large</Button>

<Button loading>Loading...</Button>
<Button disabled>Disabled</Button>

<Button>
  <PlusIcon className="w-4 h-4 mr-2" />
  With Icon
</Button>

Input

import { Input } from '@elsapiens/ui';

<Input placeholder="Enter text..." />
<Input type="email" placeholder="Email" />
<Input type="password" placeholder="Password" />
<Input error="This field is required" />
<Input disabled />

// Controlled
const [value, setValue] = useState('');
<Input value={value} onChange={(e) => setValue(e.target.value)} />

Select

import { Select } from '@elsapiens/ui';

<Select
  options={[
    { value: 'apple', label: 'Apple' },
    { value: 'banana', label: 'Banana' },
    { value: 'orange', label: 'Orange' },
  ]}
  value={selected}
  onChange={setSelected}
  placeholder="Select a fruit"
/>

SearchableSelect

import { SearchableSelect } from '@elsapiens/ui';

<SearchableSelect
  options={users}
  value={selectedUser}
  onChange={setSelectedUser}
  getOptionLabel={(user) => user.name}
  getOptionValue={(user) => user.id}
  placeholder="Search users..."
/>

SearchableTreeSelect

import { SearchableTreeSelect, type SearchableTreeSelectNode } from '@elsapiens/ui';

const categories: SearchableTreeSelectNode[] = [
  {
    id: 'electronics',
    name: 'Electronics',
    children: [
      {
        id: 'phones',
        name: 'Phones',
        children: [
          { id: 'smartphones', name: 'Smartphones' },
          { id: 'feature-phones', name: 'Feature Phones' },
        ],
      },
      { id: 'laptops', name: 'Laptops' },
      { id: 'tablets', name: 'Tablets' },
    ],
  },
  { id: 'clothing', name: 'Clothing' },
];

<SearchableTreeSelect
  nodes={categories}
  value={selectedCategory}
  onChange={setSelectedCategory}
  placeholder="Select a category..."
  searchPlaceholder="Search categories..."
/>

IconPicker

import { IconPicker } from '@elsapiens/ui';

<IconPicker
  value={selectedIcon}
  onChange={setSelectedIcon}
  placeholder="Select an icon..."
/>

DatePicker

import { DatePicker, DateRangePicker } from '@elsapiens/ui';

<DatePicker
  value={date}
  onChange={setDate}
  placeholder="Select date"
/>

<DateRangePicker
  value={dateRange}
  onChange={setDateRange}
  placeholder="Select date range"
/>

Toggle & Checkbox

import { Toggle, Checkbox, CheckboxGroup } from '@elsapiens/ui';

<Toggle checked={enabled} onChange={setEnabled} />

<Checkbox
  checked={agreed}
  onChange={setAgreed}
  label="I agree to the terms"
/>

<CheckboxGroup
  options={[
    { value: 'email', label: 'Email notifications' },
    { value: 'sms', label: 'SMS notifications' },
  ]}
  value={notifications}
  onChange={setNotifications}
/>

Display Components

Card

import {
  Card,
  CardHeader,
  CardTitle,
  CardDescription,
  CardContent,
  CardFooter,
} from '@elsapiens/ui';

<Card>
  <CardHeader>
    <CardTitle>Card Title</CardTitle>
    <CardDescription>Card description text</CardDescription>
  </CardHeader>
  <CardContent>
    <p>Card content goes here</p>
  </CardContent>
  <CardFooter>
    <Button>Action</Button>
  </CardFooter>
</Card>

// Padding variants
<Card padding="none">No padding</Card>
<Card padding="sm">Small padding</Card>
<Card padding="lg">Large padding</Card>

Badge

import { Badge } from '@elsapiens/ui';

<Badge>Default</Badge>
<Badge variant="primary">Primary</Badge>
<Badge variant="success">Success</Badge>
<Badge variant="warning">Warning</Badge>
<Badge variant="error">Error</Badge>
<Badge variant="info">Info</Badge>

<Badge size="sm">Small</Badge>
<Badge size="lg">Large</Badge>

Avatar

import { Avatar, AvatarGroup } from '@elsapiens/ui';

<Avatar src="/user.jpg" alt="John Doe" />
<Avatar src="/user.jpg" size="sm" />
<Avatar src="/user.jpg" size="lg" />
<Avatar fallback="JD" />

<AvatarGroup max={3}>
  <Avatar src="/user1.jpg" />
  <Avatar src="/user2.jpg" />
  <Avatar src="/user3.jpg" />
  <Avatar src="/user4.jpg" />
</AvatarGroup>

Table

import { Table, Badge } from '@elsapiens/ui';

const data = [
  { id: 1, name: 'John', status: 'active' },
  { id: 2, name: 'Jane', status: 'pending' },
];

<Table
  data={data}
  columns={[
    { key: 'name', header: 'Name' },
    {
      key: 'status',
      header: 'Status',
      render: (item) => (
        <Badge variant={item.status === 'active' ? 'success' : 'warning'}>
          {item.status}
        </Badge>
      ),
    },
  ]}
  striped={false}
  inCard="full"
  cardPadding="lg"
/>

Interaction Components

Modal

import { Modal, Button } from '@elsapiens/ui';

const [isOpen, setIsOpen] = useState(false);

<Button onClick={() => setIsOpen(true)}>Open Modal</Button>

<Modal
  isOpen={isOpen}
  onClose={() => setIsOpen(false)}
  title="Modal Title"
>
  <p>Modal content goes here</p>
  <div className="flex justify-end gap-2 mt-4">
    <Button variant="outline" onClick={() => setIsOpen(false)}>
      Cancel
    </Button>
    <Button onClick={handleConfirm}>Confirm</Button>
  </div>
</Modal>

Toast

import { ToastProvider, useToast, Button } from '@elsapiens/ui';

// Wrap your app
<ToastProvider>
  <App />
</ToastProvider>

// Use in components
function MyComponent() {
  const { toast } = useToast();

  return (
    <Button onClick={() => toast.success('Saved successfully!')}>
      Save
    </Button>
  );
}

// Toast variants
toast.success('Success message');
toast.error('Error message');
toast.warning('Warning message');
toast.info('Info message');

Tooltip

import { Tooltip } from '@elsapiens/ui';

<Tooltip content="This is a tooltip">
  <Button>Hover me</Button>
</Tooltip>

<Tooltip content="Bottom tooltip" side="bottom">
  <span>Hover me</span>
</Tooltip>

Chart Components

import {
  LineChart,
  AreaChart,
  BarChart,
  PieChart,
  DonutChart,
  Sparkline,
  TrendSparkline,
} from '@elsapiens/ui';

const data = [
  { month: 'Jan', revenue: 4000, expenses: 2400 },
  { month: 'Feb', revenue: 3000, expenses: 1398 },
  { month: 'Mar', revenue: 2000, expenses: 9800 },
];

// Line Chart
<LineChart
  data={data}
  xAxisKey="month"
  lines={[
    { dataKey: 'revenue', name: 'Revenue', color: 'primary' },
    { dataKey: 'expenses', name: 'Expenses', color: 'error' },
  ]}
  height={300}
  showLegend
/>

// Area Chart
<AreaChart
  data={data}
  xAxisKey="month"
  areas={[
    { dataKey: 'revenue', name: 'Revenue', color: 'primary' },
  ]}
  height={300}
/>

// Bar Chart
<BarChart
  data={data}
  xAxisKey="month"
  bars={[
    { dataKey: 'revenue', name: 'Revenue', color: 'primary' },
  ]}
  height={300}
/>

// Pie/Donut Chart
const pieData = [
  { name: 'Direct', value: 400, color: 'primary' },
  { name: 'Organic', value: 300, color: 'success' },
  { name: 'Referral', value: 200, color: 'warning' },
];

<PieChart data={pieData} height={300} />
<DonutChart
  data={pieData}
  height={300}
  centerValue="900"
  centerSubtext="Total"
/>

// Sparklines (for inline use)
<Sparkline data={[10, 20, 15, 25, 30]} width={100} height={30} />
<TrendSparkline data={[10, 20, 15, 25, 30]} type="area" />

Loading States

import { Skeleton, SkeletonText, SkeletonCard } from '@elsapiens/ui';

// Basic skeleton
<Skeleton className="h-4 w-full" />
<Skeleton className="h-10 w-10 rounded-full" />

// Text skeleton
<SkeletonText lines={3} />

// Card skeleton
<SkeletonCard />

Tabs & Stepper

import { Tabs, TabsList, TabsTrigger, TabsContent } from '@elsapiens/ui';

<Tabs defaultValue="tab1">
  <TabsList>
    <TabsTrigger value="tab1">Tab 1</TabsTrigger>
    <TabsTrigger value="tab2">Tab 2</TabsTrigger>
  </TabsList>
  <TabsContent value="tab1">Content 1</TabsContent>
  <TabsContent value="tab2">Content 2</TabsContent>
</Tabs>

import { Stepper } from '@elsapiens/ui';

<Stepper
  steps={[
    { id: 'step1', label: 'Details', status: 'completed' },
    { id: 'step2', label: 'Review', status: 'current' },
    { id: 'step3', label: 'Confirm', status: 'upcoming' },
  ]}
/>

Component Reference

Form Components

| Component | Description | |-----------|-------------| | Button | Clickable button with variants | | Input | Text input field | | Textarea | Multi-line text input | | Select | Dropdown select | | SearchableSelect | Select with search | | SearchableTreeSelect | Hierarchical tree select with search | | IconPicker | Lucide icon picker with categories and search | | MultiSelect | Multiple selection | | Combobox | Autocomplete input | | DatePicker | Date selection | | TimePicker | Time selection | | DateRangePicker | Date range selection | | NumericInput | Number input with formatting | | PhoneInput | Phone number input | | CurrencyInput | Currency input | | Toggle | On/off switch | | Checkbox | Checkbox input | | CheckboxGroup | Multiple checkboxes | | RadioGroup | Radio button group | | Slider | Range slider | | FileUpload | File upload |

Display Components

| Component | Description | |-----------|-------------| | Card | Content container | | Badge | Status/label badge | | Avatar | User avatar | | Table | Data table | | Progress | Progress bar | | Skeleton | Loading placeholder | | Tabs | Tabbed content | | Stepper | Step indicator |

Interaction Components

| Component | Description | |-----------|-------------| | Modal | Dialog modal | | ConfirmDialog | Confirmation modal | | Toast | Notification toast | | Tooltip | Hover tooltip | | Popover | Positioned popover |

Chart Components

| Component | Description | |-----------|-------------| | LineChart | Line/trend chart | | AreaChart | Area chart | | BarChart | Bar chart | | PieChart | Pie chart | | DonutChart | Donut chart | | Sparkline | Inline mini chart |

License

MIT