Skip to content

tailng/tailng-ui

Repository files navigation

TailNG logo

TailNG

Scalability of Angular. Simplicity of Tailwind.

A modern Angular 21+ component system built with Signals, Standalone APIs, and strict architectural discipline.


Build Status NPM Version License: MIT


✨ What is TailNG?

TailNG is an open-source Angular component system designed for:

  • Large applications
  • Enterprise design systems
  • Strict type safety
  • Accessibility-first development
  • Signal-based architecture
  • Tailwind-compatible styling

It combines:

  • Angular 21+
  • Standalone Components
  • Angular Signals
  • Strict ESLint architecture
  • Nx monorepo discipline
  • Optional Tailwind integration

🎯 Product Direction

TailNG is evolving toward a framework-agnostic component platform with:

  • Accessibility-first primitives built on Angular CDK and @angular/aria (experimental)
  • Wrapper abstractions that make component composition simpler for app developers
  • Additional in-house components implemented using ARIA authoring principles
  • Micro-level styling control for each component (slots, states, tokens, and hooks)
  • No required dependency on Tailwind or any specific CSS framework
  • Zero hard coupling between component behavior and styling systems
  • Shadcn-style copy/paste distribution mode in addition to package install

Risk Decision (@angular/aria)

  • Primary path: use @angular/aria as the basis for new primitives
  • Current tradeoff: accept experimental risk while Angular 22 direction matures
  • Fallback policy: do not build full CDK fallback now
  • Constraint: keep an adapter seam now so fallback can be implemented later without rewrites
  • Rule: components depend on TailNG primitive contracts, not direct @angular/aria imports

📦 Packages

Package Description
@tailng-ui/ui Main component library
@tailng-ui/cdk Behavior primitives & utilities
@tailng-ui/theme Design tokens & Tailwind adapter
@tailng-ui/icons Icon wrappers

🚀 Installation

pnpm add @tailng-ui/ui

Peer dependencies:

  • @angular/core ^21
  • @angular/common ^21
  • @angular/forms ^21

⚡ Quick Example

import { Component } from '@angular/core';
import { TngButton } from '@tailng-ui/ui';

@Component({
  standalone: true,
  imports: [TngButton],
  template: `
    <tng-button variant="primary">
      Click me
    </tng-button>
  `,
})
export class ExampleComponent {}

🏗 Architecture

TailNG follows a layered structure:

apps/ docs/ → Documentation site playground/ → Component sandbox

libs/ ui/ → Styled components cdk/ → Behavior primitives theme/ → Tokens & adapters icons/ → Icon library

Design principles:

  • Composition over prop explosion
  • Behavior separated from styling
  • Strict architectural boundaries (Nx enforced)
  • Public API discipline
  • No deep imports
  • Exhaustive state safety

🧠 Philosophy

TailNG is:

  • Headless-friendly
  • Tailwind-compatible (not required)
  • Accessibility-aware
  • Strictly typed
  • Enterprise-ready
  • Open-source forever (MIT)

We aim to provide:

  • Clean APIs
  • Predictable behavior
  • Scalable structure
  • Zero vendor lock-in

🧪 Development

Install dependencies

pnpm install

Run playground

pnpm playground

Run registry CLI playground:

pnpm dev:registry

Run docs site

pnpm docs

Build static output for Cloudflare Pages:

pnpm docs:seo

Build static playground output for Cloudflare Pages:

pnpm playground:seo

Build static vanilla playground output for Cloudflare Pages:

pnpm playground:vanilla:seo

Lint

pnpm nx run-many -t lint

Test

pnpm test

Run all library tests directly with Nx:

pnpm test:nx

Run only theme tests:

pnpm test:theme

Run CLI integration tests (tailng add ... end-to-end in temp directories):

pnpm test:cli

Run in watch mode:

pnpm nx run theme:vite:test --watch

Run with coverage:

pnpm nx run theme:vite:test --coverage

Run directly with Vitest (without Nx):

pnpm exec vitest run --config libs/tailng-ui/theme/vitest.config.ts

TailNG CLI (local)

Build and run the tailng CLI:

pnpm build:tailng
pnpm tailng -- list
pnpm tailng -- add button --cwd apps/tailng-ui/playground-vanilla --dry-run
pnpm tailng -- add button --cwd apps/tailng-ui/playground-registry --dry-run

Registry command reference:

  • List available registry items:
pnpm tailng -- list
  • Preview file generation without writing:
pnpm tailng -- add button --cwd apps/tailng-ui/playground-registry --dry-run
  • Generate files:
pnpm tailng -- add button --cwd apps/tailng-ui/playground-registry
  • Overwrite existing generated files:
pnpm tailng -- add button --cwd apps/tailng-ui/playground-registry --force

Note:

  • --dry-run shows CREATE, SKIP, or OVERWRITE behavior.
  • --cwd should point to the app root where files must be generated.
  • tailng add button follows shadcn-style source copy. It writes local files to:
    • src/app/tailng-ui/button/tng-button-primitive.ts
    • src/app/tailng-ui/button/tng-button.ts
    • src/app/tailng-ui/button/tng-button.html
    • src/app/tailng-ui/button/tng-button.css
    • src/app/tailng-ui/button/index.ts
  • Import locally in your app:
import { TngButton } from './tailng-ui/button';

🏷 Component Guidelines

  • Use Angular Signals (input())
  • Standalone components only
  • No default exports
  • Explicit return types
  • Exhaustive switch checks
  • Complexity ≤ 8
  • Max params ≤ 3
  • Accessibility-first markup
  • Strict ESLint enforced

📖 Documentation


🤝 Contributing

Contributions are welcome.

Before submitting a PR:

  • Follow ESLint rules
  • Respect architectural boundaries
  • Avoid deep imports
  • Maintain strict typing
  • Include playground demo

📜 License

MIT © 2026 TailNG

About

Material like angular components built with tailwind. Using signal pattern from angular-20 onwards

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors