npm.io
2.0.1 • Published 1 week ago

@andreagiugni/tailwind-dashboard-ui

Licence
MIT
Version
2.0.1
Deps
4
Size
1.2 MB
Vulns
0
Weekly
0

@andreagiugni/tailwind-dashboard-ui

Reusable React + Tailwind CSS v4 dashboard components extracted from TailAdmin. Every primitive ships with its Tailwind styling, extends the underlying element's native HTML attributes (so onClick, onDoubleClick, aria-*, data-*, … just work), exposes named style variants, and — where visually meaningful — accepts inline bgColor / textColor / borderColor overrides.

Dual ESM + CJS builds with TypeScript types. Core components are exported from the package root; the optional-peer widgets use the dedicated /charts, /calendar, and /editor subpaths.

Live preview

TailDashboardUI component library preview

Explore every component with interactive previews, copy-ready snippets and complete prop references at taildashboardui.com.

Install

npm i @andreagiugni/tailwind-dashboard-ui lucide-react
Peer dependencies

The core package requires:

  • React 18 or 19 (react, react-dom)
  • Tailwind CSS v4 (tailwindcss@^4)
  • Lucide React (lucide-react@^1.21.0) for the built-in component icons

clsx, tailwind-merge, and flatpickr (used by DatePicker) are bundled runtime dependencies — you do not need to install them yourself.

The following heavy libraries are optional peers, only needed if you use the matching data-viz component:

Component Optional peer deps
BarChart, LineChart apexcharts, react-apexcharts
Calendar @fullcalendar/core, @fullcalendar/react, @fullcalendar/daygrid, @fullcalendar/timegrid, @fullcalendar/list, @fullcalendar/interaction
Editor (WYSIWYG) @tiptap/react, @tiptap/pm, @tiptap/starter-kit, @tiptap/extension-link, @tiptap/extension-placeholder, @tiptap/extension-superscript, @tiptap/extension-subscript

Install only the ones for the components you use, e.g.:

npm i apexcharts react-apexcharts          # for BarChart / LineChart
npm i @tiptap/react @tiptap/pm @tiptap/starter-kit @tiptap/extension-link @tiptap/extension-placeholder @tiptap/extension-superscript @tiptap/extension-subscript  # for Editor

SSR note: the data-viz components and the Editor touch window/the DOM at render time. In server-rendered frameworks (e.g. Next.js) render them client-only — for example with next/dynamic(() => import('@andreagiugni/tailwind-dashboard-ui/charts').then(m => m.BarChart), { ssr: false }). Import them from their dedicated subpaths, so optional peers are resolved only for the feature you import and the root package stays SSR-safe and light.

ColorPicker

The ColorPicker is built on react-beautiful-color, which is a bundled dependency (installed automatically — you don't add it yourself). It is client-only and code-split like the data-viz widgets, so render it client-only under SSR. It ships its own stylesheet — import it once in your app:

import 'react-beautiful-color/dist/react-beautiful-color.css';

Pass palette to render reusable hex colors as selectable swatches below the hue and opacity sliders:

<ColorPicker palette={["#465fff", "#12b76a", "#f79009", "#f04438"]} />

Tailwind setup

The library ships its design tokens as an importable stylesheet. Add this line to your app's Tailwind entry CSS (the file that already contains @import 'tailwindcss';):

@import '@andreagiugni/tailwind-dashboard-ui/theme.css';

theme.css registers the full TailAdmin token set (brand / blue-light / gray / orange / success / error / warning palettes, --text-theme-*, --shadow-theme-*, --z-index-*) inside an @theme block, plus base layer rules.

Dark mode is driven by the .dark class. The theme defines a custom dark variant against an ancestor .dark, so toggle dark mode by adding/removing the dark class on <html> (or any ancestor):

<html class="dark">

The ThemeToggleButton component is controllable for this purpose (theme + onToggle props).

Importing components

Core components are exported from the package root:

import {
  Button,
  Badge,
  Alert,
  Input,
  Select,
  Modal,
  Table,
  TableHeader,
  TableBody,
  TableRow,
  TableCell,
  // hero-ui parity additions
  Accordion,
  AccordionItem,
  Tabs,
  Tab,
  Tooltip,
  Popover,
  Drawer,
  Chip,
  Progress,
  PollResults,
  Spinner,
  Skeleton,
  Slider,
  Code,
  Snippet,
} from '@andreagiugni/tailwind-dashboard-ui';

Heavy optional-peer components use dedicated subpaths:

import { BarChart, LineChart } from '@andreagiugni/tailwind-dashboard-ui/charts';
import { Calendar } from '@andreagiugni/tailwind-dashboard-ui/calendar';
import { Editor } from '@andreagiugni/tailwind-dashboard-ui/editor';

Props model

Three conventions apply across the library:

  1. Native handlers via HTML-attribute extension. Each component's props extend the root element's React HTML attribute type (e.g. ButtonHTMLAttributes), so every native handler and attribute (onClick, onDoubleClick, onMouseEnter, aria-*, data-*, …) is available with zero extra wiring and is forwarded onto the underlying element.
  2. Named variants. Visual states are selected with discrete props such as variant, size, and color instead of class strings.
  3. Inline color overrides. Where meaningful, components accept bgColor, textColor, and borderColor. These map to inline style (backgroundColor / color / borderColor) and let you escape the named palette for one-off colors. A consumer-supplied style prop always wins.
import { Button, Badge } from '@andreagiugni/tailwind-dashboard-ui';
import '@andreagiugni/tailwind-dashboard-ui/theme.css'; // in your Tailwind entry CSS

<Button variant="primary" onDoubleClick={handle}>Save</Button>
<Button bgColor="#ff5722" textColor="#fff">Custom</Button>
<Badge color="success">Active</Badge>

Component reference

Legend: (+native) = also extends the element's native HTML attributes. (+override) = accepts bgColor / textColor / borderColor.

Core UI
Component Key props
Button variant (primary/outline), size (sm/md), startIcon, endIcon, disabled, (+native button) (+override)
Badge variant (light/solid), color (primary/success/error/warning/info/light/dark), size (sm/md), startIcon, endIcon, (+native span) (+override)
Ribbon variant (corner/rounded/flag), color (primary/success/error/warning/info/dark), position (top-left/top-right/bottom-left/bottom-right), children (label), (+native span) (+override) — place inside a relative host (corner needs overflow-hidden)
Alert variant (success/error/warning/info), title, message, showLink, linkHref, linkText, icon? (override icon), (+native div)
Avatar src, alt, size (xsmall…xxlarge), status (online/offline/busy/none), statusColor?, (+native img)
AvatarText children, className, (+native div)
Dropdown isOpen, onClose, children, portal? (default true, prevents clipping inside cards/tables/overflow containers), triggerRef? (optional custom trigger anchor), (+native div)
DropdownItem variant (default/primary/outline, like Button), icon?, bgColor/textColor/borderColor overrides, tag (a/button), href, onClick, onItemClick, baseClassName (full override)
Modal isOpen, onClose, title? (wrapping header aligned with close button), showCloseButton, isFullscreen, closeOnBackdrop?, closeOnEsc?; alert preset → variant (confirm/error/warning) + animated SVG icon, title, description, actionText?, onAction?; (+native div)
Table (composable) TableHeader / TableBody / TableRow / TableCell with children, isHeader (cell), (+native table elements; onClick / onDoubleClick on rows & cells)
Table (data-driven) pass data + columns (key, header, sortable?, align?, render?, className?) to get search + three-state per-column sort (neutral/ascending/descending) + pagination: rowsPerPage? (max rows/page, default 10), rowsPerPageOptions?, searchKeys? (search box shown only when provided), searchPlaceholder?, defaultSortKey? / defaultSortDirection?, pagination?, paginationAlign? (left/center/right/full, default right), showSizeSelector?, onRowClick?, getRowId?, emptyContent?
Pagination currentPage, totalPages, onPageChange, align? (left/center/right/full — full pins Previous/Next to the edges with page indices centered)
Breadcrumb pageTitle, items?, (+native)
ThemeToggleButton theme? (controlled), onToggle?, (+native button)
Card title?, description?, icon?, image?, imageAlt?, horizontal?, footer?, children?, (+native div) (+override)
Accordion / AccordionItem selectionMode (single/multiple), expandedKeys / defaultExpandedKeys, onExpandedChange; item: itemKey, title, startContent?, disabled
Tabs / Tab variant (underline/solid/pill), selectedKey / defaultSelectedKey, onSelectionChange, color?; tab: tabKey, title, disabled
Chip color, variant (light/solid), size, startIcon, endIcon, avatar?, onClose?, (+native span) (+override)
Code color (primary/success/error/warning/info/default), size (sm/md), (+native code) (+override)
Snippet code (string | string[]), symbol?, hideCopyButton?, hideSymbol?, size, (+override)
Progress value, maxValue?, color, size (sm/md/lg), label?, showValueLabel?, isIndeterminate?
PollResults options ({ label, value?, series? }[]), maxValue?, size (sm/md/lg), color, trackColor?, showValueLabel?, showSeriesLabels?, valueFormatter?, labelTextSize?/labelTextColor?/labelTextWeight?, valueTextSize?/valueTextColor?/valueTextWeight?, seriesLabelTextSize?/seriesLabelTextColor?/seriesLabelTextWeight?, seriesValueTextSize?/seriesValueTextColor?/seriesValueTextWeight?, (+native div) (+override)
Spinner size (sm/md/lg), color, label?
Skeleton isLoaded, width?, height?, className, children?
Toast variant (success/danger/warning/info), position? (left/center/right), duration? (ms), title, message?, icon?, hideIcon?, showCloseButton?, onClose?, hideAccentBar?, (+native div) (+override)
Overlays
Component Key props
Tooltip content, placement (top/right/bottom/left), delay?, disabled?, (+native span) (+override)
Popover trigger, placement, isOpen? / defaultOpen? / onOpenChange?, closeOnOutsideClick?, closeOnEsc?, portal? (default true, prevents clipping inside cards/overflow containers)
Drawer isOpen, onClose, placement (left/right/top/bottom), showCloseButton?, closeOnBackdrop?, closeOnEsc?, size?, (+native div)
Form controls
Component Key props
Input type, value / defaultValue, onChange, success, error, hint, disabled, (+native input) (+override)
Label htmlFor, children, (+native label)
Select options ({ value, label, icon? }[]), placeholder, defaultValue, onChange(value), disabled, searchable? (default false, filters labels with a search input), portal? (default true, prevents clipping inside tables/cards). Without search, typing a prefix scrolls to a matching option; repeated letters cycle matches. Arrow keys navigate, Enter selects, Escape cancels.
MultiSelect options, selected / defaultSelected, onChange, placeholder, disabled, portal? (default true, prevents clipping inside tables/cards)
Checkbox label, checked, onChange(checked), disabled, checkedColor?
Radio / RadioSm id, name, value, checked, label, onChange(value), disabled
Switch label?, checked / defaultChecked, onChange(checked), color (blue/gray), disabled
TextArea value, onChange, rows, success, error, hint, disabled
FileInput onChange, accept, multiple, (+native input)
PasswordInput password field with a show/hide eye toggle, (+native input attrs)
Dropzone onDrop(files), accept?, multiple?, title?, description?, browseLabel? — drag-and-drop upload, dependency-free
DatePicker id, mode (single/multiple/range/time), defaultDate, onChange, label, placeholder — calendar is appended to document.body to avoid clipping inside cards/overflow containers
DateTimePicker id, label?, placeholder?, defaultDate?, defaultTime? ("HH:MM"), onChange?({ date, time }) — flatpickr date calendar appended to document.body + a compact HH:MM time input
Slider value / defaultValue, onChange(value), min, max, step, color, label?, showValue?, disabled
ColorPicker defaultValue? (hex), defaultFormat? / formats? (hex/rgb/rgba/hsl/hsla), showInput?, withEyeDropper?, palette? (hex colors), label?, onChange?(value, color) — compact swatch + formatted value trigger opening a saturation/hue/alpha popup with selectable palette colors, value input, format switcher and clear-value button; built on react-beautiful-color (bundled), client-only, import its CSS (see ColorPicker note above)
Editor (WYSIWYG) content, onChange(html), placeholder?, editable?, toolbar? (ordered tool ids or custom buttons), rows? (minimum visible text rows, default 8), editorClassName? — optional Tiptap peers; render client-only (see Data viz)
Data viz

These wrap optional heavy peer deps and must be rendered client-only under SSR (see the SSR note in Peer dependencies).

Component Key props
BarChart series, categories, colors?, barColors? (per-option bar colors), height?, horizontal?, showBarValues?, showBarPercentages?, minBarWidth? (fixed px minimum for horizontal bars, default 30), percentageMode?, barValueFormatter?, barPercentageFormatter?, options? (merged over defaults)
LineChart series, categories, colors?, height?, options?
Calendar events, onEventClick, onDateSelect, initialView
Editor (WYSIWYG) content, onChange(html), placeholder?, editable?, toolbar?, rows? — Tiptap-powered, customizable toolbar

The data-viz components default their data to sensible demo values, so they render out-of-the-box and are fully overridable via the props above.

The Editor is a Tiptap-powered rich-text editor with a fully customizable toolbar. Pass an ordered toolbar array of built-in tool ids ("bold" | "italic" | "strike" | "code" | "superscript" | "subscript" | "heading1" | "heading2" | "heading3" | "bulletList" | "orderedList" | "blockquote" | "codeBlock" | "link" | "undo" | "redo" | "divider") or custom { id, icon, title, onClick, isActive? } button objects. Set editable={false} for a read-only view (toolbar hidden). Use rows to control the minimum visible text rows and therefore the editor content height.

import dynamic from 'next/dynamic';
const Editor = dynamic(
  () => import('@andreagiugni/tailwind-dashboard-ui/editor').then((m) => m.Editor),
  { ssr: false }
);

<Editor
  content="<p>Hello <strong>world</strong></p>"
  onChange={(html) => save(html)}
  toolbar={['bold', 'italic', 'divider', 'bulletList', 'orderedList', 'link']}
  rows={10}
/>

Table

Table has two modes, both under the same component:

  1. Composable — use Table / TableHeader / TableBody / TableRow / TableCell as thin, styled wrappers around the native table elements when you want full control over the markup.
  2. Data-driven — pass a data array and a columns definition and you get live search, per-column click-to-sort, a "Show N entries" selector and pagination out of the box. The mode switches on automatically as soon as columns is provided.
import { Table, type TableColumn } from '@andreagiugni/tailwind-dashboard-ui';

type Person = { name: string; office: string; salary: number };

const people: Person[] = [
  { name: 'Abram Schleifer', office: 'Edinburgh', salary: 89500 },
  { name: 'Carla George', office: 'London', salary: 15500 },
  // …
];

const columns: TableColumn<Person>[] = [
  { key: 'name', header: 'User', sortable: true },
  { key: 'office', header: 'Office', sortable: true },
  {
    key: 'salary',
    header: 'Salary',
    sortable: true,
    align: 'right',
    render: (row) => `$${row.salary.toLocaleString()}`, // custom cell
  },
];

<Table
  data={people}
  columns={columns}
  rowsPerPage={5}              // max rows per page (default 10)
  rowsPerPageOptions={[5, 10, 25]}
  defaultSortKey="name"
  searchKeys={['name', 'office']} // omit to hide the search box
  onRowClick={(row) => console.log(row)}
/>

Key data-driven props: data, columns (each: key, header, sortable?, align?, render?, className?), rowsPerPage (default 10), rowsPerPageOptions (default [5,10,25,50]), searchKeys / searchPlaceholder, defaultSortKey / defaultSortDirection, pagination, paginationAlign (left / center / right / full, default right), showSizeSelector, onRowClick, getRowId, emptyContent.

Search visibility: the search input renders only when you pass a non-empty searchKeys array — those are also the exact fields the query matches. Omit searchKeys (or pass []) to hide search entirely.

License

MIT Andrea Giugni