A modern, customizable React component library featuring seamless Tailwind CSS integration, interactive UI elements, and optimized for developer productivity.
npm install compouish
npm install compoui
`
π¨ Tailwind CSS Setup
If you are using Tailwind CSS, add the following to your tailwind.config.js file:
`js
module.exports = {
content: ["./node_modules/compoui/dist/*/.{js,ts,jsx,tsx}"],
theme: {
extend: {},
},
plugins: [],
};
`
β Non-Tailwind Users
If you are not using Tailwind CSS, import the default styles into your project:
`ts
import "/compoui/dist/style.css";
`
---
π Usage
$3
`tsx
import React from "react";
import { AuthForm } from "compoui";
import { User, Phone } from "lucide-react"; // Example icons
const MyAuthForm = () => {
const handleSubmit = (data: Record) => {
console.log("Form submitted:", data);
};
return (
onSubmit={handleSubmit}
title="Sign In"
buttonText="Login"
customFields={[
{
name: "username",
type: "text",
placeholder: "Enter your username",
icon: ,
isRequired: true,
},
{
name: "phone",
type: "tel",
placeholder: "Enter your phone number",
icon: ,
isRequired: false,
},
]}
/>
);
};
export default MyAuthForm;
`
#### Props Table
| Prop Name | Type | Description | Required? |
| --------------------- | ---------------------------------------------------------------------------------------------------- | ------------------------------------ | --------- |
| onSubmit | (data: Record | Function to handle form submission | β No |
| loading | boolean | Displays a loading state | β No |
| error | string | Displays an error message | β No |
| title | string | Sets the form title | β No |
| emailPlaceholder | string | Placeholder for email input | β No |
| passwordPlaceholder | string | Placeholder for password input | β No |
| buttonText | string | Text for submit button | β No |
| loadingText | string | Text when button is in loading state | β No |
| customFields | Array<{name: string, type: string, placeholder: string, icon?: JSX.Element, isRequired?: boolean}> | Array of custom input fields | β No |
| formStyle | string | Custom class for form styling | β No |
| buttonStyle | string | Custom class for button styling | β No |
| iconColor | string | Color for icons in custom fields | β No |
---
$3
`tsx
import React from "react";
import Button from "./Button";
import { ArrowRight, User } from "lucide-react";
export default function App() {
return (
);
}
`
#### Props Table
| Prop Name | Type | Description | Required? |
| ----------- | --------------------------------------------------------- | ---------------------------------- | --------- |
| size | "sm" \| "md" \| "lg" | Sets button size | β No |
| color | "blue" \| "red" \| "green" \| "black" \| "etc" | Button color | β No |
| onClick | () => void | Function called on click | β No |
| leftIcon | LucideIcon | Icon component to display on left | β No |
| rightIcon | LucideIcon | Icon component to display on right | β No |
---
$3
`tsx
import { SideBar } from "compoui";
import { Home, Table, Gift, User } from "lucide-react"; // Icons
const MySidebar = () => {
return (
sections={[
{
title: "Home",
path: "/", // Navigates to Home
icon: ,
},
{
title: "Profile",
onClick: () => alert("Profile clicked!"), // Only executes function
icon: ,
},
{
title: "Dashboard",
path: "/dashboard",
onClick: () => console.log("Navigating to dashboard..."), // Both navigate & run function
icon:
,
},
{
title: "Gifts",
icon: , // No action, just display the title and the icon
},
]}
/>
);
};
export default MySidebar;
`
#### Props Table
| Prop Name | Type | Description | Required? |
| ------------------- | --------------------------------------------------------------------------------- | ---------------------------- | --------- |
| sections | Array<{title: string, path?: string, icon?: JSX.Element, onClick?: () => void}> | List of sidebar sections | β
Yes |
| sideStyle | string | Custom sidebar styling | β No |
| toggleButtonStyle | string | Custom toggle button styling | β No |
| navStyle | string | Custom nav styling | β No |
---
$3
`tsx
import React from "react";
import { Layout } from "compoui";
import { Home, Search, User, Bell } from "lucide-react";
const MyLayout = () => {
return (
title="Dashboard"
layoutColor="blue"
isSearchVisible={true}
searchTitle="Search..."
onSearchChange={(query) => console.log("Search query:", query)}
sections={[
{ title: "Home", path: "/", icon: },
{ title: "Profile", path: "/profile", icon: },
]}
icons={[
{
title: "Notification",
icon: ,
onClick: () => alert("Notification!"),
},
]}
>
Welcome to Dashboard
This is your main content area. The sidebar can be toggled on any
screen size.
);
};
export default MyLayout;
`
#### Props Table
| Prop Name | Type | Description | Required? |
| ----------------- | ------------------------------------------------------------------------------------ | ---------------------------------- | --------- |
| sections | Array<{ title: string, path?: string, icon?: JSX.Element, onClick?: () => void }> | Sidebar sections | β
Yes |
| icons | Array<{ title?: string, path?: string, icon?: JSX.Element, onClick?: () => void }> | Action icons | β No |
| isIconsVisible | boolean | Shows/hides action icons | β No |
| isSearchVisible | boolean | Shows search input | β No |
| children | React.ReactNode | Page content | β
Yes |
| title | string | Layout title | β No |
| layoutColor | string | Layout background color | β No |
| searchTitle | string | Placeholder for search input | β No |
| onSearchChange | (query: string) => void | Callback function for search input | β No |
---
---
π Alert Component
$3
`tsx
import React from "react";
import Alert from "./Alert";
export default function App() {
return (
message="Something went wrong!"
type="error"
onClose={() => console.log("Alert closed")}
/>
);
}
`
$3
| Prop | Type | Default | Description |
| ----------- | --------------------------------------------- | -------- | ---------------------------------------- |
| message | React.ReactNode | β | The message to display inside the alert. |
| type | "success" \| "error" \| "warning" \| "info" | "info" | Defines the alert style. |
| duration | number | β | Auto-dismiss time (ms). |
| onClose | () => void | β | Callback when alert is closed. |
| className | string | β | Additional TailwindCSS classes. |
---
π Card Component
$3
`tsx
import React from "react";
import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from "./Card";
import Button from "./Button";
export default function App() {
return (
Product Title
Brief description goes here
This is the card content. You can put anything inside: text, images, or forms.
);
}
``
$3
| Component | Prop | Type | Default | Description |
| ----------------- | ----------- | ----------- | ------- | ------------------------------ |
| Card | children | ReactNode | β | Content inside the card. |
| | className | string | β | Extra TailwindCSS classes. |
| CardHeader | children | ReactNode | β | Header content. |
| CardTitle | children | ReactNode | β | Card title text. |
| CardDescription | children | ReactNode | β | Small description text. |
| CardContent | children | ReactNode | β | Main content body. |
| CardFooter | children | ReactNode | β | Footer actions (e.g. buttons). |
---
β¬οΈ Dropdown Component
$3
`tsx
import React from "react";
import Dropdown from "./Dropdown";
import { User, Settings } from "lucide-react";
export default function App() {
return (
options={[
{ label: "Profile", value: "profile", icon: },
{ label: "Settings", value: "settings", icon: },
]}
placeholder="Choose an option"
onChange={(val) => console.log("Selected:", val)}
/>
);
}
`
$3
| Prop | Type | Default | Description |
| -------------- | ------------------------------------------------------ | -------------------- | ----------------------------------------- |
| options | { label: string; value: string; icon?: ReactNode }[] | β | Dropdown items. |
| placeholder | string | "Select an option" | Text shown when nothing selected. |
| searchable | boolean | true | Enable search input inside dropdown. |
| notFoundText | string | "No results found" | Text shown when search yields no results. |
| onChange | (value: string) => void | β | Callback when option is selected. |
| className | string | β | Extra TailwindCSS classes. |
---
πͺ Modal Component
$3
`tsx
import React, { useState } from "react";
import Modal from "./Modal";
export default function App() {
const [open, setOpen] = useState(false);
return (
onClick={() => setOpen(true)}
className="px-4 py-2 bg-blue-600 text-white rounded-lg"
>
Open Modal
isOpen={open}
onClose={() => setOpen(false)}
title="Delete Item"
description="Are you sure you want to delete this item?"
cancelText="No"
confirmText="Yes, delete"
confirmColor="red"
onConfirm={() => alert("Deleted!")}
>
This action cannot be undone.
);
}
``
$3
| Prop | Type | Default | Description |
| ----------------- | ----------------------------------------------------------- | ----------- | ------------------------------------------- |
| isOpen | boolean | β | Controls modal visibility. |
| onClose | () => void | β | Called when modal is closed. |
| title | string | β | Optional modal title. |
| description | string | β | Optional description text. |
| children | ReactNode | β | Extra content inside modal body. |
| cancelText | string | "Cancel" | Label for cancel button. |
| cancelColor | Color string ("blue", "red", "green", "gray", etc.) | "gray" | Cancel button color. |
| onCancel | () => void | β | Called when cancel is clicked. |
| confirmText | string | "Confirm" | Label for confirm button. |
| confirmColor | Color string ("blue", "red", "green", "gray", etc.) | "blue" | Confirm button color. |
| onConfirm | () => void | β | Called when confirm is clicked. |
| showCloseButton | boolean | true | Show/hide "X" close button. |
| closeOnBackdrop | boolean | true | Allow closing modal when clicking backdrop. |
---
π ProgressBar Component
$3
`tsx
import React from "react";
import ProgressBar from "./ProgressBar";
export default function App() {
return (
);
}
`
$3
| Prop | Type | Default | Description |
| ----------- | ---------------------------------------------------------------------------------------- | ----------- | ------------------------------------------- |
| value | number | β | Current progress value. |
| max | number | 100 | Maximum progress value. |
| size | "xs" \| "sm" \| "md" \| "lg" \| "xl" | "md" | Height of the progress bar. |
| color | "blue" \| "green" \| "red" | "blue" | Color variant. |
| showLabel | boolean | false | Show percentage text. |
| label | string | β | Custom label (replaces default percentage). |
| className | string | β | Extra TailwindCSS classes. |
---
$3
#### Example
`tsx
import Spinner from "./Spinner";
;
`
#### Props
| Prop | Type | Default | Description |
| ----------- | -------------------------------------- | ---------------- | ------------------------------- |
| size | "xs" \| "sm" \| "md" \| "lg" \| "xl" | "md" | Controls spinner size. |
| color | string | "currentColor" | CSS color value for spinner. |
| className | string | "" | Extra Tailwind/utility classes. |
---
$3
#### Example
`tsx
import Tabs from "./Tabs";
const tabs = [
{ label: "Home", value: "home", content: Welcome! },
{ label: "Profile", value: "profile", content: Your profile },
];
;
`
#### Props
| Prop | Type | Default | Description |
| -------------- | -------- | --------------- | ------------------------------------- |
| tabs | Tab[] | required | Array of { label, value, content }. |
| defaultValue | string | tabs[0].value | Initial active tab. |
| className | string | "" | Extra Tailwind/utility classes. |
---
$3
#### Example
`tsx
import Tooltip from "./Tooltip";
;
`
#### Props
| Prop | Type | Default | Description |
| ----------- | ---------------------------------------- | ------------ | ----------------------------------- |
| children | ReactNode | required | Element to wrap. |
| content | ReactNode | required | Tooltip text/content. |
| position | "top" \| "bottom" \| "left" \| "right" | "top" | Tooltip placement. |
| delay | number | 200 | Delay in ms before showing tooltip. |
| className | string | "" | Extra Tailwind/utility classes. |
---
Perfect π Since you want more detailed documentation for the Table component, we can expand the README.md with full details of TableProps, TableColumn, TableAction, TableTranslations, and TableColors.
Hereβs the improved README.md section for Table:
---
π Table
A powerful, feature-rich data table with:
β
Sorting β’ β
Searching β’ β
Pagination β’ β
Row Actions β’ β
i18n Translations β’ β
Loading state
---
$3
`tsx
import Table from "./Table";
import { Edit, Trash } from "lucide-react";
type User = { id: number; name: string; email: string };
const users: User[] = [
{ id: 1, name: "Alice", email: "alice@mail.com" },
{ id: 2, name: "Bob", email: "bob@mail.com" },
];
const columns = [
{ key: "name", label: "Name", sortable: true },
{ key: "email", label: "Email" },
];
const actions = [
{
label: "Edit",
icon: ,
onClick: (row: User) => console.log("Edit", row),
},
{
label: "Delete",
icon: ,
onClick: (row: User) => console.log("Delete", row),
color: "red",
},
];
title="Users"
data={users}
columns={columns}
actions={actions}
pageSize={5}
onCreate={() => console.log("Create new user")}
onRefresh={() => console.log("Refresh data")}
onExport={() => console.log("Export")}
onImport={() => console.log("Import")}
/>;
`
---
$3
| Prop | Type | Default | Description |
| ----------------------- | ---------------------------- | ----------------- | -------------------------------------- |
| data | T[] | required | Array of rows to display. |
| columns | TableColumn | required | Column definitions (see below). |
| actions | TableAction | [] | Action buttons per row. |
| pageSize | number | 5 | Rows per page. |
| onRowClick | (row: T) => void | undefined | Called when a row is clicked. |
| className | string | "" | Extra Tailwind/utility classes. |
| title | string | "Data Table" | Table title in the header. |
| loading | boolean | false | Show loading spinner overlay. |
| head | boolean | true | Show header (title, search, controls). |
| onImport | () => void | undefined | Callback for import button. |
| onExport | () => void | undefined | Callback for export button. |
| onRefresh | () => void | undefined | Callback for refresh button. |
| onCreate | () => void | undefined | Callback for create button. |
| createButtonColor | keyof TableColors | "blue" | Color for create button. |
| importButtonColor | keyof TableColors | "red" | Color for import button. |
| exportButtonColor | keyof TableColors | "orange" | Color for export button. |
| refreshButtonColor | keyof TableColors | "black" | Color for refresh button. |
| paginationButtonColor | keyof TableColors | "white" | Color for active pagination button. |
| translations | Partial | defaults provided | Override built-in i18n translations. |
---
$3
`ts
export interface TableColumn {
key: keyof T; // Data key
label: string; // Column header label
sortable?: boolean; // Enables sorting
width?: string; // Optional column width
}
`
Example:
`ts
const columns = [
{ key: "name", label: "Name", sortable: true },
{ key: "email", label: "Email" },
];
`
---
$3
`ts
export interface TableAction {
label: string; // Action button text
icon: React.ReactNode; // Icon to display
onClick: (row: T) => void; // Callback when clicked
color?: keyof TableColors; // Optional color
}
`
Example:
`ts
const actions = [
{
label: "Edit",
icon: ,
onClick: (row) => console.log("Edit", row),
},
{
label: "Delete",
icon: ,
onClick: (row) => console.log("Delete", row),
color: "red",
},
];
`
---
$3
Supports full i18n customization:
`ts
export interface TableTranslations {
title: string;
create: string;
import: string;
export: string;
refresh: string;
rowsPerPage: string;
total: string;
first: string;
last: string;
searchPlaceholder: string;
loading: string;
noResults: string;
showing: (start: number, end: number, total: number) => string;
}
`
Default:
`ts
const defaultTranslations = {
title: "Data Table",
create: "Create",
import: "Import",
export: "Export",
refresh: "Refresh",
rowsPerPage: "Rows per page:",
total: "total entries",
first: "First",
last: "Last",
searchPlaceholder: "Search across all columns...",
loading: "Loading...",
noResults: "No results found",
showing: (start, end, total) =>
Showing ${start} to ${end} of ${total} results,
};
`
---
$3
#### Available Colors
blue, red, green, yellow, gray, indigo, purple, pink, orange, teal, cyan, lime, emerald, fuchsia, rose, slate, zinc, neutral, stone, black, white
---
π¨ Customization
Some components allows style customization through props. You can override default styles using:
- Custom Tailwind classes
- Bootstrap classes
- Your own CSS styles
$3
`tsx
`
$3
`tsx
``