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

@iamrraj/drk-ui-components

v1.1.2

Published

A comprehensive React component library built with TypeScript and Tailwind CSS. Accessible, customizable, and production-ready components.

Readme

DRK UI Components

A comprehensive React component library built with TypeScript and Tailwind CSS. Provides accessible, customizable, and production-ready UI components.

npm version License: MIT

🎮 Live Demo

View Interactive Demo →

Try out all components with live examples, dark/light theme toggle, and copy-ready code snippets.

📚 Documentation

Complete Documentation →

Comprehensive documentation with interactive examples, API reference, and usage guides for all components.

Features

32+ Production-Ready Components - Complete UI toolkit for modern web applications

🎨 Tailwind CSS Support - Full customization with utility classes

🧱 Variant-Rich Primitives - Buttons, inputs, cards, and badges ship with polished variants and size controls

🧊 Layout Utilities - Re-usable Stack and cn helpers for building consistent spacing and class composition

🔧 TypeScript First - Complete type definitions for better DX

Accessible - ARIA compliant and keyboard navigable

🎯 Tree-Shakeable - Import only what you need

📱 Responsive - Mobile-first design approach

🎭 Customizable Primary Color - Easy theme customization

🔔 Toast Notifications - Beautiful notification system with provider pattern

🧭 Advanced Sidebar - Collapsible navigation with nested menus

Loading States - Spinners, skeletons, and progress bars

🎪 Form Components - Checkboxes, radios, and more

🚀 Lightweight - Only ~50 kB package size for fast installations

🛠 Productivity Hooks - Ready-to-use useDisclosure, useMediaQuery, and color scheme detection

Installation

npm install @iamrraj/drk-ui-components react react-dom

or

yarn add @iamrraj/drk-ui-components react react-dom

Peer Dependencies

{
  "react": "^19.0.0",
  "react-dom": "^19.0.0"
}

Additional Dependencies (Included)

The library uses these icon libraries (already included):

  • react-icons - For general icons
  • lucide-react - For the Info icon

Setup

1. Import Component Styles

Import the component library CSS in your main entry file (e.g., main.tsx):

import "@iamrraj/drk-ui-components/dist/index.css";
import "./index.css"; // Your app's CSS

2. Configure Tailwind CSS v4 (Required)

IMPORTANT: This library requires Tailwind CSS v4 with the new @import syntax.

Install Tailwind CSS v4 and the PostCSS plugin:

npm install -D tailwindcss@4 @tailwindcss/postcss

Create or update postcss.config.cjs:

module.exports = {
  plugins: {
    "@tailwindcss/postcss": {},
    autoprefixer: {},
  },
};

Update your main CSS file (e.g., src/index.css) to use Tailwind v4 syntax:

@import "tailwindcss";

@theme {
  /* Optional: customize the primary color */
  --color-primary-50: #f0f9ff;
  --color-primary-100: #e0f2fe;
  --color-primary-200: #bae6fd;
  --color-primary-300: #7dd3fc;
  --color-primary-400: #38bdf8;
  --color-primary-500: #0ea5e9;
  --color-primary-600: #0284c7;
  --color-primary-700: #0369a1;
  --color-primary-800: #075985;
  --color-primary-900: #0c4a6e;
}

/* Your custom styles */

Important: Make sure your tailwind.config.js does NOT scan the node_modules folder to avoid conflicts:

/** @type {import('tailwindcss').Config} */
export default {
  content: [
    "./index.html",
    "./src/**/*.{js,ts,jsx,tsx}",
    // Do NOT include node_modules
  ],
};

3. Customize Primary Color (Optional)

You can customize the primary color by overriding the CSS variables in your @theme block:

@theme {
  /* Your custom primary color */
  --color-primary-50: #fef2f2;
  --color-primary-100: #fee2e2;
  --color-primary-200: #fecaca;
  --color-primary-300: #fca5a5;
  --color-primary-400: #f87171;
  --color-primary-500: #ef4444;  /* Main primary color */
  --color-primary-600: #dc2626;
  --color-primary-700: #b91c1c;
  --color-primary-800: #991b1b;
  --color-primary-900: #7f1d1d;
}

Components

Basic Components

  • Button - Customizable button component
  • Card - Container for grouped content
  • Input - Text input with label and validation
  • Label - Form label with helper text support
  • Heading - Semantic heading (h1-h6)
  • Paragraph - Text paragraph component
  • Span - Inline text component
  • Badge - Status indicators and labels

Form Components

  • Toggle - On/off switch component
  • Textarea - Multi-line text input with validation
  • Slider - Range slider for numeric inputs
  • Checkbox - Checkbox input with label and helper text
  • Radio - Radio button with label and helper text
  • Dropdown - Single-select dropdown with search
  • CustomMultiSelect - Multi-select dropdown with filtering

Navigation Components

  • Sidebar - Collapsible sidebar with nested menu, logo, user section, and settings
  • Pagination - Page navigation with customizable display
  • Tabs - Tab navigation with icons and disabled states

Overlay Components

  • Modal - Dialog with focus trapping
  • ConfirmationModal - Confirmation dialog for actions
  • Sheet - Sliding drawer with accessible structure and overlay
  • Popover - Triggered floating panel for quick menus and details
  • Tooltip - Info icon with hover tooltip
  • TooltipWrapper - Wrap any element with tooltip support

Toast Components

  • Toast - Toast notification with auto-dismiss
  • ToastProvider - Provider for toast notifications
  • useToast - Hook for triggering toasts

Loading & Feedback Components

  • Spinner - Loading spinner with multiple sizes
  • Skeleton - Loading placeholder with pulse animation
  • Progress - Progress bar with percentage
  • Alert - Alert/banner with variants (info, success, warning, error)

Display Components

  • Avatar - User avatar with image, initials, or icon fallback
  • Divider - Content separator (horizontal/vertical)
  • VisuallyHidden - Accessibility helper for screen-reader-only content

Layout Components

  • Accordion - Collapsible content panels with single/multiple open
  • Stack - Flex helper for directional spacing and alignment

Data Display Components

  • Table - Data table with sorting and custom rendering

Utilities

  • cn - Lightweight class name merger exported for convenience
  • Hooks - useDisclosure, useMediaQuery, usePrefersColorScheme

Complete Props Reference

For detailed prop information for all components, see PROPS_REFERENCE.md

Usage Examples

Button

import { Button } from "@iamrraj/drk-ui-components";
import { BiDownload } from "react-icons/bi";

function App() {
  return (
    <div className="flex flex-wrap gap-3">
      <Button variant="primary" endIcon={<BiDownload className="h-4 w-4" />}>
        Download
      </Button>

      <Button variant="outline" size="sm">
        Outline
      </Button>

      <Button variant="ghost" loading loadingText="Saving...">
        Save Changes
      </Button>
    </div>
  );
}

Input

import { Input } from "@iamrraj/drk-ui-components";
import { BiEnvelope, BiLock } from "react-icons/bi";
import { useState } from "react";

function LoginForm() {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");

  return (
    <div className="space-y-4">
      <Input
        name="email"
        label="Email Address"
        type="email"
        placeholder="[email protected]"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
        leftIcon={<BiEnvelope className="h-4 w-4" />}
        helperText="We'll never share your email"
      />

      <Input
        name="password"
        type="password"
        label="Password"
        placeholder="Enter a strong password"
        value={password}
        onChange={(e) => setPassword(e.target.value)}
        leftIcon={<BiLock className="h-4 w-4" />}
        variant="filled"
        inputSize="lg"
        error={password.length > 0 && password.length < 12}
        errorMessage="At least 12 characters required"
      />
    </div>
  );
}

Stack

import { Avatar, Heading, Paragraph, Stack } from "@iamrraj/drk-ui-components";

function TeamMember() {
  return (
    <Stack direction="row" gap="lg" align="center" className="p-4">
      <Avatar name="Rahul Raj" />
      <div>
        <Heading level={4}>Rahul Raj</Heading>
        <Paragraph className="text-gray-500">
          Building delightful frontend experiences.
        </Paragraph>
      </div>
    </Stack>
  );
}

Hooks

import { useDisclosure, useMediaQuery, usePrefersColorScheme } from "@iamrraj/drk-ui-components";

function ResponsivePanel() {
  const disclosure = useDisclosure();
  const isDesktop = useMediaQuery("(min-width: 1024px)");
  const preferredScheme = usePrefersColorScheme();

  return (
    <div className="space-y-4">
      <p className="text-sm text-gray-500">
        Preferred color scheme: <strong>{preferredScheme}</strong>
      </p>

      <Button onClick={disclosure.toggle}>
        {disclosure.isOpen ? "Hide" : "Show"} Filters
      </Button>

      {disclosure.isOpen && (
        <Card className="p-4">
          <Paragraph>This panel {isDesktop ? "sticks" : "slides"} based on viewport size.</Paragraph>
        </Card>
      )}
    </div>
  );
}

Dropdown

import { Dropdown } from "@iamrraj/drk-ui-components";
import type { DropdownOption } from "@iamrraj/drk-ui-components";
import { useState } from "react";

function CountrySelector() {
  const countries: DropdownOption[] = [
    { id: "us", label: "United States" },
    { id: "uk", label: "United Kingdom" },
    { id: "ca", label: "Canada" },
  ];

  const [selected, setSelected] = useState<DropdownOption | null>(null);

  return (
    <Dropdown
      options={countries}
      selectedOption={selected}
      onSelect={setSelected}
      placeholder="Select a country"
      className="bg-gray-50" // Custom background - user classes take priority
    />
  );
}

Customization Note: The className prop allows full customization. User-provided classes take priority over defaults, so you can override any styling including background colors, borders, padding, etc.

CustomMultiSelect

import { CustomMultiSelect } from "@iamrraj/drk-ui-components";
import { useState } from "react";

function FrameworkSelector() {
  const frameworks = [
    { id: "1", name: "React" },
    { id: "2", name: "Vue" },
    { id: "3", name: "Angular" },
    { id: "4", name: "Svelte" },
  ];

  const [selected, setSelected] = useState<string[]>([]);

  return (
    <CustomMultiSelect
      options={frameworks}
      selectedItems={selected}
      onSelect={setSelected}
      label="Select Frameworks"
      placeholder="Choose frameworks"
      multiple={true}
      classes="bg-blue-50 hover:bg-blue-100" // Custom styling - user classes take priority
    />
  );
}

Customization Note: The classes prop allows full customization. User-provided classes take priority over defaults, enabling complete control over the component's appearance.

Modal

import { Modal, Button, Input } from "@iamrraj/drk-ui-components";
import { useState } from "react";

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

  return (
    <>
      <Button onClick={() => setIsOpen(true)}>Edit Profile</Button>

      {isOpen && (
        <Modal className="max-w-2xl p-6">
          <h2 className="text-2xl font-bold mb-4">Edit Profile</h2>
          <Input label="Name" placeholder="Enter your name" className="mb-4" />
          <Input
            label="Email"
            type="email"
            placeholder="[email protected]"
            className="mb-4"
          />
          <div className="flex justify-end gap-2 mt-6">
            <Button
              onClick={() => setIsOpen(false)}
              className="bg-gray-200 px-4 py-2 rounded"
            >
              Cancel
            </Button>
            <Button className="bg-primary-500 text-white px-4 py-2 rounded">
              Save
            </Button>
          </div>
        </Modal>
      )}
    </>
  );
}

ConfirmationModal

import { ConfirmationModal, Button } from "@iamrraj/drk-ui-components";
import { useState } from "react";

function DeleteButton() {
  const [showModal, setShowModal] = useState(false);

  const handleDelete = () => {
    console.log("Item deleted");
    setShowModal(false);
  };

  return (
    <>
      <Button
        onClick={() => setShowModal(true)}
        className="bg-red-500 text-white px-4 py-2 rounded"
      >
        Delete Item
      </Button>

      <ConfirmationModal
        isOpen={showModal}
        onClose={() => setShowModal(false)}
        onConfirm={handleDelete}
        title="Delete Item?"
        message="Are you sure you want to delete this item? This action cannot be undone."
      />
    </>
  );
}

Popover

import {
  Popover,
  PopoverTrigger,
  PopoverContent,
  PopoverClose,
  Button,
  Stack,
} from "@iamrraj/drk-ui-components";

function ActionsPopover() {
  return (
    <Popover>
      <PopoverTrigger>
        <Button variant="outline">More actions</Button>
      </PopoverTrigger>
      <PopoverContent className="space-y-1">
        <Stack gap="xs">
          <Button variant="ghost">Rename</Button>
          <Button variant="ghost">Duplicate</Button>
          <PopoverClose>
            <Button variant="ghost" className="text-red-600">
              Delete
            </Button>
          </PopoverClose>
        </Stack>
      </PopoverContent>
    </Popover>
  );
}

Sheet

import {
  Sheet,
  SheetTrigger,
  SheetContent,
  SheetHeader,
  SheetTitle,
  SheetDescription,
  SheetFooter,
  SheetClose,
  Button,
  Input,
  Stack,
} from "@iamrraj/drk-ui-components";

function FilterSheet() {
  return (
    <Sheet>
      <SheetTrigger>
        <Button>Open filters</Button>
      </SheetTrigger>
      <SheetContent side="right" className="max-w-md">
        <SheetHeader>
          <SheetTitle>Project filters</SheetTitle>
          <SheetDescription>Refine the project list using tags and owners.</SheetDescription>
        </SheetHeader>

        <Stack gap="md" className="py-4">
          <Input label="Owner" placeholder="Search teammates" />
          <Input label="Tag" placeholder="Design, Backend, ..." />
        </Stack>

        <SheetFooter>
          <SheetClose>
            <Button variant="outline">Cancel</Button>
          </SheetClose>
          <Button variant="primary">Apply filters</Button>
        </SheetFooter>
      </SheetContent>
    </Sheet>
  );
}

Toggle

import { Toggle } from "@iamrraj/drk-ui-components";
import { useState } from "react";

function Settings() {
  const [darkMode, setDarkMode] = useState(false);

  return (
    <Toggle
      checked={darkMode}
      onChange={setDarkMode}
      label="Dark Mode"
      helper_text="Enable dark theme for better visibility"
    />
  );
}

Badge

import { Badge } from "@iamrraj/drk-ui-components";

function StatusIndicator() {
  return (
    <div className="flex gap-2">
      <Badge variant="green">Active</Badge>
      <Badge variant="red">Error</Badge>
      <Badge variant="yellow">Warning</Badge>
      <Badge variant="blue">Info</Badge>
      <Badge variant="gray">Inactive</Badge>
    </div>
  );
}

TooltipWrapper

import { TooltipWrapper, Button } from "@iamrraj/drk-ui-components";

function ActionButtons() {
  return (
    <div className="flex gap-2">
      <TooltipWrapper tooltipContent="Save your changes">
        <Button className="bg-blue-500 text-white px-4 py-2 rounded">
          Save
        </Button>
      </TooltipWrapper>

      <TooltipWrapper tooltipContent="Delete permanently" placement="bottom">
        <Button className="bg-red-500 text-white px-4 py-2 rounded">
          Delete
        </Button>
      </TooltipWrapper>
    </div>
  );
}

Complete Form Example

import {
  Input,
  Dropdown,
  CustomMultiSelect,
  Toggle,
  Button,
  Card,
  Heading,
} from "@iamrraj/drk-ui-components";
import { useState } from "react";

function CompleteForm() {
  const [formData, setFormData] = useState({
    name: "",
    email: "",
    country: null,
    frameworks: [],
    notifications: true,
  });

  const countries = [
    { id: "us", label: "United States" },
    { id: "uk", label: "United Kingdom" },
  ];

  const frameworks = [
    { id: "1", name: "React" },
    { id: "2", name: "Vue" },
  ];

  const handleSubmit = (e) => {
    e.preventDefault();
    console.log("Form data:", formData);
  };

  return (
    <Card className="max-w-2xl mx-auto p-6 bg-white rounded-lg shadow-lg">
      <Heading as="h2" className="text-2xl font-bold mb-6">
        Registration Form
      </Heading>

      <form onSubmit={handleSubmit} className="space-y-4">
        <Input
          label="Full Name"
          placeholder="John Doe"
          value={formData.name}
          onChange={(e) => setFormData({ ...formData, name: e.target.value })}
          required
        />

        <Input
          label="Email"
          type="email"
          placeholder="[email protected]"
          value={formData.email}
          onChange={(e) => setFormData({ ...formData, email: e.target.value })}
          required
        />

        <Dropdown
          options={countries}
          selectedOption={formData.country}
          onSelect={(country) => setFormData({ ...formData, country })}
          placeholder="Select your country"
        />

        <CustomMultiSelect
          options={frameworks}
          selectedItems={formData.frameworks}
          onSelect={(frameworks) => setFormData({ ...formData, frameworks })}
          label="Frameworks"
          placeholder="Select frameworks you know"
        />

        <Toggle
          checked={formData.notifications}
          onChange={(notifications) =>
            setFormData({ ...formData, notifications })
          }
          label="Email Notifications"
        />

        <Button
          type="submit"
          className="w-full bg-primary-500 text-white py-3 rounded-lg hover:bg-primary-600 transition-colors"
        >
          Submit
        </Button>
      </form>
    </Card>
  );
}

Toast Notifications

import { ToastProvider, useToast } from "@iamrraj/drk-ui-components";

// Wrap your app with ToastProvider
function App() {
  return (
    <ToastProvider position="right" theme="dark">
      <YourApp />
    </ToastProvider>
  );
}

// Use the useToast hook in any component
function MyComponent() {
  const toast = useToast();

  const handleSuccess = () => {
    toast.success("Success!", "Your changes have been saved");
  };

  const handleError = () => {
    toast.error("Error!", "Something went wrong", 5000);
  };

  const handleWarning = () => {
    toast.warning("Warning!", "Please check your input");
  };

  const handleInfo = () => {
    toast.info("Info", "New updates available");
  };

  return (
    <div>
      <button onClick={handleSuccess}>Show Success</button>
      <button onClick={handleError}>Show Error</button>
      <button onClick={handleWarning}>Show Warning</button>
      <button onClick={handleInfo}>Show Info</button>
    </div>
  );
}

Sidebar

import { Sidebar } from "@iamrraj/drk-ui-components";
import { BiHome, BiUser, BiFolder, BiChart, BiSettings, BiCog, BiLogOut } from "react-icons/bi";
import { useState } from "react";

function App() {
  const [collapsed, setCollapsed] = useState(false);
  const [activePath, setActivePath] = useState("/dashboard");

  const menuItems = [
    {
      id: "1",
      label: "Dashboard",
      icon: <BiHome />,
      url: "/dashboard",
      active: activePath === "/dashboard",
    },
    {
      id: "2",
      label: "Users",
      icon: <BiUser />,
      badge: 12,
      children: [
        { id: "2-1", label: "All Users", url: "/users" },
        { id: "2-2", label: "Add User", url: "/users/new" },
        { id: "2-3", label: "User Roles", url: "/users/roles" },
      ],
    },
    {
      id: "3",
      label: "Projects",
      icon: <BiFolder />,
      url: "/projects",
      badge: "NEW",
    },
    {
      id: "4",
      label: "Analytics",
      icon: <BiChart />,
      url: "/analytics",
      divider: true,
    },
    {
      id: "5",
      label: "Settings",
      icon: <BiSettings />,
      url: "/settings",
    },
  ];

  const user = {
    name: "John Doe",
    email: "[email protected]",
    avatar: "https://example.com/avatar.jpg",
    initials: "JD",
    role: "Admin",
  };

  // Custom user menu items (v1.0.7+)
  const userMenuItems = [
    {
      id: "profile",
      label: "View Profile",
      icon: <BiUser />,
      onClick: () => console.log("Profile clicked"),
    },
    {
      id: "settings",
      label: "Settings",
      icon: <BiCog />,
      onClick: () => console.log("Settings clicked"),
      divider: true,
    },
    {
      id: "logout",
      label: "Logout",
      icon: <BiLogOut />,
      onClick: () => console.log("Logout clicked"),
      destructive: true, // Red styling for destructive actions
    },
  ];

  return (
    <div className="flex h-screen">
      <Sidebar
        logo={<img src="/logo.png" alt="Logo" className="h-8" />}
        menuItems={menuItems}
        user={user}
        userMenuItems={userMenuItems} // Custom user dropdown menu
        collapsed={collapsed}
        onCollapse={setCollapsed}
        onNavigate={(url) => {
          console.log("Navigate to:", url);
          setActivePath(url);
        }}
      />
      <main className="flex-1 p-8">{/* Your content */}</main>
    </div>
  );
}

Spinner

import { Spinner } from "@iamrraj/drk-ui-components";

function LoadingPage() {
  return (
    <div className="flex justify-center items-center min-h-screen">
      <Spinner size="lg" />
    </div>
  );
}

// Inline loading
function SubmitButton() {
  const [loading, setLoading] = useState(false);

  return (
    <button className="flex items-center gap-2 px-4 py-2 bg-blue-500 text-white rounded">
      {loading && <Spinner size="sm" color="border-white" />}
      {loading ? "Saving..." : "Save"}
    </button>
  );
}

Skeleton

import { Skeleton } from "@iamrraj/drk-ui-components";

function UserCardLoading() {
  return (
    <div className="p-4 border rounded-lg">
      <Skeleton circle width="4rem" height="4rem" />
      <Skeleton width="200px" className="mt-4" />
      <Skeleton count={3} className="mt-2" />
    </div>
  );
}

Avatar

import { Avatar } from "@iamrraj/drk-ui-components";

function UserList() {
  return (
    <div className="flex items-center gap-3">
      <Avatar
        src="https://example.com/avatar.jpg"
        alt="John Doe"
        size="lg"
      />
      <Avatar initials="JD" size="md" className="bg-blue-500" />
      <Avatar initials="AB" size="sm" className="bg-gradient-to-r from-purple-500 to-pink-500" />
    </div>
  );
}

Progress

import { Progress } from "@iamrraj/drk-ui-components";
import { useState, useEffect } from "react";

function UploadProgress() {
  const [progress, setProgress] = useState(0);

  useEffect(() => {
    const timer = setInterval(() => {
      setProgress((prev) => (prev >= 100 ? 0 : prev + 10));
    }, 500);
    return () => clearInterval(timer);
  }, []);

  return (
    <div className="w-full max-w-md">
      <Progress value={progress} showLabel size="lg" />
    </div>
  );
}

Alert

import { Alert } from "@iamrraj/drk-ui-components";
import { useState } from "react";

function Notifications() {
  const [showAlert, setShowAlert] = useState(true);

  return (
    <div className="space-y-4">
      <Alert variant="success" title="Success!">
        Your profile has been updated successfully.
      </Alert>

      <Alert variant="error" dismissible onDismiss={() => setShowAlert(false)}>
        An error occurred while processing your request.
      </Alert>

      <Alert variant="warning" title="Warning">
        Your session will expire in 5 minutes.
      </Alert>

      <Alert variant="info">
        New features are now available. Check them out!
      </Alert>
    </div>
  );
}

Checkbox

import { Checkbox } from "@iamrraj/drk-ui-components";
import { useState } from "react";

function Settings() {
  const [notifications, setNotifications] = useState(false);
  const [newsletter, setNewsletter] = useState(true);

  return (
    <div className="space-y-4">
      <Checkbox
        checked={notifications}
        onChange={setNotifications}
        label="Enable notifications"
        helperText="Receive email notifications for updates"
      />
      <Checkbox
        checked={newsletter}
        onChange={setNewsletter}
        label="Subscribe to newsletter"
      />
    </div>
  );
}

Radio

import { Radio } from "@iamrraj/drk-ui-components";
import { useState } from "react";

function PaymentMethod() {
  const [method, setMethod] = useState("card");

  return (
    <div className="space-y-3">
      <Radio
        name="payment"
        value="card"
        checked={method === "card"}
        onChange={setMethod}
        label="Credit Card"
        helperText="Pay with Visa, MasterCard, or AmEx"
      />
      <Radio
        name="payment"
        value="paypal"
        checked={method === "paypal"}
        onChange={setMethod}
        label="PayPal"
      />
      <Radio
        name="payment"
        value="bank"
        checked={method === "bank"}
        onChange={setMethod}
        label="Bank Transfer"
      />
    </div>
  );
}

Divider

import { Divider } from "@iamrraj/drk-ui-components";

function Content() {
  return (
    <div>
      <section>Top Content</section>
      <Divider />
      <section>Bottom Content</section>

      {/* Divider with text */}
      <Divider text="OR" />

      {/* Vertical divider */}
      <div className="flex items-center gap-4">
        <button>Left</button>
        <Divider orientation="vertical" className="h-8" />
        <button>Right</button>
      </div>
    </div>
  );
}

Textarea

import { Textarea } from "@iamrraj/drk-ui-components";
import { useState } from "react";

function FeedbackForm() {
  const [feedback, setFeedback] = useState("");

  return (
    <Textarea
      label="Your Feedback"
      placeholder="Tell us what you think..."
      value={feedback}
      onChange={(e) => setFeedback(e.target.value)}
      rows={5}
      helperText="Maximum 500 characters"
      required
    />
  );
}

Slider

import { Slider } from "@iamrraj/drk-ui-components";
import { useState } from "react";

function VolumeControl() {
  const [volume, setVolume] = useState(50);

  return (
    <div className="w-full max-w-md">
      <Slider
        label="Volume"
        value={volume}
        onChange={setVolume}
        min={0}
        max={100}
        step={5}
        showValue
      />
    </div>
  );
}

Accordion

import { Accordion } from "@iamrraj/drk-ui-components";

function FAQSection() {
  const faqItems = [
    {
      id: "1",
      title: "What is DRK UI Components?",
      content:
        "A comprehensive React component library with 32+ production-ready components built with TypeScript and Tailwind CSS.",
    },
    {
      id: "2",
      title: "How do I install it?",
      content: "Run: npm install @iamrraj/drk-ui-components",
    },
    {
      id: "3",
      title: "Is it free to use?",
      content: "Yes! It's completely free and open-source under the MIT license.",
    },
  ];

  return (
    <div className="max-w-2xl mx-auto">
      <h2 className="text-2xl font-bold mb-4">Frequently Asked Questions</h2>
      <Accordion items={faqItems} />
    </div>
  );
}

Tabs

import { Tabs } from "@iamrraj/drk-ui-components";
import { BiHome, BiUser, BiChart } from "react-icons/bi";
import { useState } from "react";

function Dashboard() {
  const [activeTab, setActiveTab] = useState("overview");

  const tabs = [
    { id: "overview", label: "Overview", icon: <BiHome /> },
    { id: "users", label: "Users", icon: <BiUser /> },
    { id: "analytics", label: "Analytics", icon: <BiChart /> },
    { id: "disabled", label: "Disabled", disabled: true },
  ];

  return (
    <div>
      <Tabs tabs={tabs} activeTab={activeTab} onChange={setActiveTab} />

      <div className="p-6">
        {activeTab === "overview" && <div>Overview content</div>}
        {activeTab === "users" && <div>Users content</div>}
        {activeTab === "analytics" && <div>Analytics content</div>}
      </div>
    </div>
  );
}

Pagination

import { Pagination } from "@iamrraj/drk-ui-components";
import { useState } from "react";

function DataList() {
  const [currentPage, setCurrentPage] = useState(1);
  const totalPages = 20;

  return (
    <div>
      {/* Your data content */}
      <div className="my-8">
        {/* Data items for page {currentPage} */}
      </div>

      <div className="flex justify-center">
        <Pagination
          currentPage={currentPage}
          totalPages={totalPages}
          onPageChange={setCurrentPage}
        />
      </div>
    </div>
  );
}

Table

import { Table, Badge } from "@iamrraj/drk-ui-components";
import type { TableColumn } from "@iamrraj/drk-ui-components";

function UserTable() {
  const users = [
    { id: 1, name: "Alice Johnson", role: "Developer", status: "Active", projects: 12 },
    { id: 2, name: "Bob Smith", role: "Designer", status: "Active", projects: 8 },
    { id: 3, name: "Carol White", role: "Manager", status: "Away", projects: 15 },
  ];

  const columns: TableColumn<typeof users[0]>[] = [
    {
      key: "name",
      header: "Name",
      sortable: true,
    },
    {
      key: "role",
      header: "Role",
      sortable: true,
    },
    {
      key: "status",
      header: "Status",
      sortable: false,
      render: (user) => (
        <Badge variant={user.status === "Active" ? "green" : "yellow"}>
          {user.status}
        </Badge>
      ),
    },
    {
      key: "projects",
      header: "Projects",
      sortable: true,
    },
  ];

  return (
    <div className="overflow-hidden rounded-xl border">
      <Table data={users} columns={columns} striped hoverable />
    </div>
  );
}

TypeScript Support

All components are fully typed. Import types using the import type syntax:

import type {
  ButtonProps,
  InputProps,
  DropdownOption,
} from "@iamrraj/drk-ui-components";

Or import components and types separately:

import { Button, Input, Dropdown } from "@iamrraj/drk-ui-components";
import type {
  ButtonProps,
  InputProps,
  DropdownOption,
} from "@iamrraj/drk-ui-components";

Styling

Using Tailwind Classes

All components accept a className prop for custom styling:

<Button className="bg-gradient-to-r from-purple-500 to-pink-500 text-white font-bold py-3 px-6 rounded-full shadow-lg hover:shadow-xl transform hover:scale-105 transition-all duration-200">
  Fancy Button
</Button>

Component-Specific Styling

  • Button: No default styles, fully customizable
  • Card: Minimal styling, acts as a container
  • Input: Pre-styled with focus states
  • Badge: 7 color variants (gray, red, green, blue, yellow, purple, primary)

Browser Support

  • Chrome (latest)
  • Firefox (latest)
  • Safari (latest)
  • Edge (latest)

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT © DRK

Changelog

v1.0.7

  • Enhanced Sidebar with User Menu Dropdown - Added userMenuItems prop
  • User dropdown at bottom shows profile info (name, email, role)
  • Custom menu items with icons and destructive styling support
  • Portal rendering for user dropdown menu
  • Click outside to close functionality
  • Smooth animations and transitions

v1.0.6

  • 15 New Components Added!
  • Sidebar - Collapsible navigation with nested menus, badges, and user section
  • Spinner - Loading spinner with 4 sizes (sm, md, lg, xl)
  • Skeleton - Loading placeholder with pulse animation
  • Avatar - User avatar with image, initials, and icon fallback
  • Progress - Progress bar with percentage display
  • Alert - Alert/banner with 4 variants (info, success, warning, error)
  • Checkbox - Checkbox input with label and helper text
  • Radio - Radio button with label and helper text
  • Textarea - Multi-line text input with validation
  • Slider - Range slider for numeric inputs
  • Accordion - Collapsible content panels
  • Tabs - Tab navigation with icons and disabled states
  • Pagination - Page navigation with ellipsis
  • Table - Sortable data table with custom rendering
  • Divider - Content separator (horizontal/vertical)
  • Now 32+ production-ready components!

v1.0.5

  • Fixed import statements in README (removed double @iamrraj/@iamrraj)
  • Added beautiful SVG component preview visualization
  • Corrected CSS and Toast import paths

v1.0.4

  • Enhanced Dropdown & CustomMultiSelect with React Portal rendering
  • Menu positioning improved - opens directly under input
  • User classes now take priority over defaults for better customization
  • Updated documentation with custom styling examples
  • Added new live demo link

v1.0.2

  • Dramatically reduced package size from 2.24 MB to 45 kB (98% reduction!)
  • Disabled source maps in production builds
  • Added .npmignore to exclude unnecessary files
  • Optimized package for faster downloads and installations

v1.0.1

  • Added Toast Component and ToastProvider
  • Added useToast hook for notifications
  • Complete TypeScript types for Toast components

v1.0.0

  • Initial release
  • 17+ components
  • Full TypeScript support
  • Tailwind CSS integration
  • Customizable primary color

Support

For issues and questions, please open an issue on GitHub.