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

nilaui

v0.0.13

Published

A modern, reusable Angular UI component library with 14 components including layout elements, built with standalone components and Tailwind CSS.

Readme

NilaUI - Angular Component Library

A modern, reusable Angular UI component library with 14 components including layout elements, built with standalone components and Tailwind CSS.

📖 Complete Documentation

Visit the official documentation site for detailed guides, live examples, and API references:

🔗 https://nilaui.web.app/


Overview

NilaUI provides a comprehensive set of UI components for building beautiful Angular applications. All components are standalone, tree-shakable, and designed to work seamlessly with Tailwind CSS.

Supported Angular: 21.x (Angular 19-20 should also work)


Installation

npm install nilaui

Global Setup

Required: Tailwind CSS Configuration

Add these custom color tokens to your Tailwind theme:

/* styles.css */
@import "tailwindcss";

@theme {
  --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;

  --color-secondary-100: #f1f5f9;
  --color-secondary-200: #e2e8f0;
  --color-secondary-500: #64748b;
  --color-secondary-800: #1e293b;
  --color-secondary-900: #0f172a;

  --color-success-50: #f0fdf4;
  --color-success-100: #dcfce7;
  --color-success-200: #bbf7d0;
  --color-success-600: #16a34a;
  --color-success-800: #166534;
  --color-success-900: #14532d;

  --color-warning-50: #fffbeb;
  --color-warning-100: #fef3c7;
  --color-warning-200: #fde68a;
  --color-warning-600: #d97706;
  --color-warning-800: #92400e;
  --color-warning-900: #78350f;

  --color-destructive-50: #fef2f2;
  --color-destructive-100: #fee2e2;
  --color-destructive-200: #fecaca;
  --color-destructive-500: #ef4444;
  --color-destructive-600: #dc2626;
  --color-destructive-700: #b91c1c;
  --color-destructive-800: #991b1b;
  --color-destructive-900: #7f1d1d;

  --color-muted-50: #f9fafb;
  --color-muted-100: #f3f4f6;
  --color-muted-200: #e5e7eb;
  --color-muted-300: #d1d5db;
  --color-muted-400: #9ca3af;
  --color-muted-500: #6b7280;
  --color-muted-600: #4b5563;
}

Components

Alert

Displays important messages with contextual styling.

import { Alert } from 'nilaui';
<ui-alert variant="success" title="Success!" [dismissible]="true" (dismissed)="onDismiss()">
  Your changes have been saved.
</ui-alert>

| Input | Type | Default | Description | |-------|------|---------|-------------| | variant | 'default' \| 'success' \| 'warning' \| 'destructive' | 'default' | Visual style | | title | string | '' | Optional title | | dismissible | boolean | false | Show dismiss button |

| Output | Payload | Description | |--------|---------|-------------| | dismissed | void | Emitted when dismissed |


Avatar

Displays user profile images or initials.

import { Avatar } from 'nilaui';
<ui-avatar src="avatar.jpg" name="John Doe" size="lg"></ui-avatar>

| Input | Type | Default | Description | |-------|------|---------|-------------| | src | string | '' | Image URL | | name | string | '' | Name for initials fallback | | size | 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' | 'md' | Size |


Badge

Small status indicators and labels.

import { Badge } from 'nilaui';
<ui-badge variant="success">Active</ui-badge>

| Input | Type | Default | Description | |-------|------|---------|-------------| | variant | 'default' \| 'secondary' \| 'success' \| 'warning' \| 'destructive' \| 'outline' | 'default' | Visual style |


Button

Interactive button with multiple variants and states.

import { Button } from 'nilaui';
<ui-button variant="default" [loading]="isLoading" (clicked)="save()">
  Save Changes
</ui-button>

| Input | Type | Default | Description | |-------|------|---------|-------------| | variant | 'default' \| 'secondary' \| 'destructive' \| 'outline' \| 'ghost' \| 'link' | 'default' | Visual style | | size | 'sm' \| 'md' \| 'lg' \| 'icon' | 'md' | Size | | type | 'button' \| 'submit' \| 'reset' | 'button' | HTML type | | disabled | boolean | false | Disabled state | | loading | boolean | false | Loading state | | fullWidth | boolean | false | Full width |

| Output | Payload | Description | |--------|---------|-------------| | clicked | void | Click event |


Card

Container with header, content, and footer sections.

import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from 'nilaui';
<ui-card variant="elevated">
  <ui-card-header>
    <ui-card-title>Settings</ui-card-title>
    <ui-card-description>Manage your preferences</ui-card-description>
  </ui-card-header>
  <ui-card-content>Content here...</ui-card-content>
  <ui-card-footer>
    <ui-button>Save</ui-button>
  </ui-card-footer>
</ui-card>

| Input | Type | Default | Description | |-------|------|---------|-------------| | variant | 'default' \| 'bordered' \| 'elevated' | 'default' | Visual style | | padding | 'none' \| 'sm' \| 'md' \| 'lg' | 'md' | Inner padding |


Datepicker

Calendar-based date picker with form control support.

import { Datepicker } from 'nilaui';
<ui-datepicker 
  label="Start Date" 
  placeholder="Select start date"
  [minDate]="minDate"
  [maxDate]="maxDate"
  formControlName="startDate"
  (dateChange)="onDateChange($event)"
></ui-datepicker>

| Input | Type | Default | Description | |-------|------|---------|-------------| | label | string | '' | Field label | | placeholder | string | 'Select date' | Placeholder text | | hint | string | '' | Help text | | error | string | '' | Error message | | required | boolean | false | Required indicator | | disabled | boolean | false | Disabled state | | minDate | Date \| null | null | Minimum selectable date | | maxDate | Date \| null | null | Maximum selectable date |

| Output | Payload | Description | |--------|---------|-------------| | dateChange | Date \| null | Selected date changed |

Features:

  • Calendar dropdown with month navigation
  • Today button and clear button
  • Min/max date constraints
  • Implements ControlValueAccessor for reactive forms

Dialog

Modal dialog with backdrop and keyboard support.

import { Dialog, DialogHeader, DialogTitle, DialogDescription, DialogContent, DialogFooter } from 'nilaui';
<ui-dialog [open]="isOpen" (closed)="isOpen = false" size="md">
  <ui-dialog-header>
    <ui-dialog-title>Confirm Action</ui-dialog-title>
  </ui-dialog-header>
  <ui-dialog-content>Are you sure?</ui-dialog-content>
  <ui-dialog-footer>
    <ui-button variant="outline" (clicked)="isOpen = false">Cancel</ui-button>
    <ui-button (clicked)="confirm()">Confirm</ui-button>
  </ui-dialog-footer>
</ui-dialog>

| Input | Type | Default | Description | |-------|------|---------|-------------| | open | boolean | false | Visibility | | size | 'sm' \| 'md' \| 'lg' \| 'xl' \| 'full' | 'md' | Width | | closeOnBackdrop | boolean | true | Close on backdrop click | | closeOnEscape | boolean | true | Close on Escape key |

| Output | Payload | Description | |--------|---------|-------------| | closed | void | Close event |


Dropdown

Dropdown menu with items and separators.

import { Dropdown, DropdownItem, DropdownSeparator, DropdownLabel } from 'nilaui';
<ui-dropdown align="right">
  <button trigger>Options</button>
  <ui-dropdown-label>Actions</ui-dropdown-label>
  <ui-dropdown-item (selected)="edit()">Edit</ui-dropdown-item>
  <ui-dropdown-separator></ui-dropdown-separator>
  <ui-dropdown-item (selected)="delete()">Delete</ui-dropdown-item>
</ui-dropdown>

| Input | Type | Default | Description | |-------|------|---------|-------------| | align | 'left' \| 'right' | 'left' | Menu alignment | | width | 'auto' \| 'trigger' \| 'sm' \| 'md' \| 'lg' | 'auto' | Menu width |


EmptyState

Placeholder for empty data states.

import { EmptyState } from 'nilaui';
<ui-empty-state title="No results" description="Try adjusting your search.">
  <ui-button action (clicked)="clearSearch()">Clear Search</ui-button>
</ui-empty-state>

| Input | Type | Default | Description | |-------|------|---------|-------------| | title | string | 'No data found' | Heading | | description | string | '' | Description text | | icon | boolean | false | Use custom icon slot |


Input / Textarea

Form inputs with validation support (implements ControlValueAccessor).

import { Input, Textarea } from 'nilaui';
<ui-input label="Email" type="email" [error]="emailError" formControlName="email"></ui-input>
<ui-textarea label="Description" [rows]="6" formControlName="description"></ui-textarea>

| Input | Type | Default | Description | |-------|------|---------|-------------| | label | string | '' | Field label | | placeholder | string | '' | Placeholder | | hint | string | '' | Help text | | error | string | '' | Error message | | required | boolean | false | Required indicator | | disabled | boolean | false | Disabled state | | rows | number (Textarea) | 4 | Visible rows |


Skeleton

Loading placeholders.

import { Skeleton, SkeletonCard, SkeletonTable } from 'nilaui';
<ui-skeleton variant="text" width="60%"></ui-skeleton>
<ui-skeleton variant="circular" width="48px" height="48px"></ui-skeleton>
<ui-skeleton-card></ui-skeleton-card>
<ui-skeleton-table [rowCount]="5"></ui-skeleton-table>

| Input | Type | Default | Description | |-------|------|---------|-------------| | variant | 'text' \| 'circular' \| 'rectangular' | 'text' | Shape | | width | string | '100%' | Width | | height | string | '' | Height | | rowCount (SkeletonTable) | number | 5 | Number of rows |


Table

Data table with pagination.

import { Table, TableHeader, TableBody, TableRow, TableHead, TableCell, TablePagination } from 'nilaui';
<ui-table>
  <ui-table-header>
    <ui-table-row>
      <ui-table-head>Name</ui-table-head>
      <ui-table-head align="right">Actions</ui-table-head>
    </ui-table-row>
  </ui-table-header>
  <ui-table-body>
    @for (item of items; track item.id) {
      <ui-table-row>
        <ui-table-cell>{{ item.name }}</ui-table-cell>
        <ui-table-cell align="right">...</ui-table-cell>
      </ui-table-row>
    }
  </ui-table-body>
</ui-table>
<ui-table-pagination [total]="100" [pageSize]="10" [currentPage]="page" (pageChange)="onPage($event)"></ui-table-pagination>

TableHead/TableCell Input: align: 'left' | 'center' | 'right' (default: 'left')


Tabs

Tabbed content navigation.

import { Tabs, TabContent } from 'nilaui';
<ui-tabs [tabs]="[{value:'a',label:'Tab A'},{value:'b',label:'Tab B'}]" #tabs>
  <ui-tab-content value="a" [activeValue]="tabs.activeTab()">Content A</ui-tab-content>
  <ui-tab-content value="b" [activeValue]="tabs.activeTab()">Content B</ui-tab-content>
</ui-tabs>

| Input | Type | Default | Description | |-------|------|---------|-------------| | tabs | {value:string,label:string}[] | required | Tab definitions | | defaultValue | string | '' | Initially active tab |

| Output | Payload | Description | |--------|---------|-------------| | tabChange | string | Tab change event |


Layout Components

Sidebar

Left-side navigation menu for dashboards.

import { Sidebar, SidebarItem } from 'nilaui';
<ui-sidebar 
  [items]="menuItems" 
  [activeItemId]="activeRoute"
  [collapsed]="isCollapsed"
  [theme]="'light'"
  (itemClick)="navigate($event)"
  (collapsedChange)="isCollapsed = $event"
>
  <div header>
    <img src="logo.png" alt="Logo" />
  </div>
  <div footer>
    <span>v1.0.0</span>
  </div>
</ui-sidebar>
menuItems: SidebarItem[] = [
  { id: 'dashboard', label: 'Dashboard', icon: '<svg>...</svg>' },
  { 
    id: 'users', 
    label: 'Users', 
    children: [
      { id: 'list', label: 'All Users' },
      { id: 'add', label: 'Add User' }
    ]
  }
];

| Input | Type | Default | Description | |-------|------|---------|-------------| | items | SidebarItem[] | [] | Menu items | | activeItemId | string | '' | Currently active item | | collapsed | boolean | false | Collapsed state | | width | string | '256px' | Expanded width | | collapsedWidth | string | '64px' | Collapsed width | | theme | 'light' \| 'dark' | 'light' | Color theme |

| Output | Payload | Description | |--------|---------|-------------| | itemClick | SidebarItem | Item clicked | | collapsedChange | boolean | Collapse toggle |

Content Slots: [header], [footer]


Navbar

Top navigation bar.

import { Navbar, NavbarItem } from 'nilaui';
<ui-navbar 
  [items]="navItems"
  [activeItemId]="activeNav"
  [sticky]="true"
  (itemClick)="navigate($event)"
  (menuToggle)="sidebar.openMobile()"
>
  <div brand>
    <img src="logo.png" alt="Logo" class="h-8" />
    <span class="ml-2 font-semibold">MyApp</span>
  </div>
  <div actions>
    <ui-avatar name="John Doe" size="sm"></ui-avatar>
  </div>
</ui-navbar>

| Input | Type | Default | Description | |-------|------|---------|-------------| | items | NavbarItem[] | [] | Navigation items | | activeItemId | string | '' | Currently active item | | height | string | '64px' | Navbar height | | sticky | boolean | true | Stick to top | | elevated | boolean | true | Show bottom border | | theme | 'light' \| 'dark' | 'light' | Color theme |

| Output | Payload | Description | |--------|---------|-------------| | itemClick | NavbarItem | Item clicked | | menuToggle | void | Mobile menu button clicked |

Content Slots: [brand], [actions]


Build & Publish

# Build library
ng build nilaui

# Publish to npm
cd dist/nilaui
npm publish --access public

Contribution Guidelines

  1. All components must be standalone
  2. Follow Angular Style Guide
  3. Use TypeScript strict mode
  4. Test components before submitting PRs
  5. Update this README when adding components

License

MIT