Nx + Angular 21 + Tailwind starter for TailNG.
apps/docs– demo & docs siteapps/playground– sandbox for testing componentslibs/ui– UI component library (Button, Input, Card, etc.)libs/icons– Bootstrap Icons wrapperlibs/theme– Tailwind preset + pluginlibs/cdk– utilities
yarn installThe playground is a development sandbox where you can test and preview components:
yarn playgroundThis will start the playground application at http://localhost:4200 (or the next available port).
yarn docsComponents are organized in the libs/ui directory:
libs/ui/
├── button/
│ └── src/
│ ├── button.component.ts
│ ├── button.component.html
│ ├── button.types.ts
│ ├── button.variants.ts
│ └── public-api.ts
├── input/
│ └── src/
│ ├── input.component.ts
│ ├── input.component.html
│ └── public-api.ts
└── src/
└── public-api.ts (main export file)
-
Create the component directory in
libs/ui/:mkdir -p libs/ui/my-component/src
-
Create the component TypeScript file (
libs/ui/my-component/src/my-component.component.ts):import { Component, input } from '@angular/core'; @Component({ selector: 'tng-my-component', standalone: true, templateUrl: './my-component.component.html', }) export class TailngMyComponentComponent { // Define your inputs using Angular signals label = input<string>(''); disabled = input(false); }
-
Create the component template (
libs/ui/my-component/src/my-component.component.html):<div class="my-component"> <span>{{ label() }}</span> </div>
-
Create the public API file (
libs/ui/my-component/src/public-api.ts):export * from './my-component.component';
-
Export from main UI library (
libs/ui/src/public-api.ts):export * from '../my-component/src/public-api';
-
Determine the category for your component:
- Form Controls:
apps/playground/src/app/demos/form-controls/ - Buttons & Indicators:
apps/playground/src/app/demos/buttons-indicators/ - Layout:
apps/playground/src/app/demos/layout/ - Navigation:
apps/playground/src/app/demos/navigation/ - Popups & Overlays:
apps/playground/src/app/demos/popups-overlays/ - Data Table & Structure:
apps/playground/src/app/demos/data-table-structure/
- Form Controls:
-
Create the demo component directory:
mkdir -p apps/playground/src/app/demos/[category]/my-component
-
Create the demo component (
my-component-demo.component.ts):import { Component } from '@angular/core'; import { TailngMyComponentComponent } from '@tailng-ui/ui'; @Component({ selector: 'playground-my-component-demo', standalone: true, imports: [TailngMyComponentComponent], templateUrl: './my-component-demo.component.html', }) export class MyComponentDemoComponent {}
-
Create the demo template (
my-component-demo.component.html):<div> <h1 class="text-2xl font-bold mb-6">My Component</h1> <div class="space-y-6"> <section> <h2 class="text-lg font-semibold mb-3">Basic Usage</h2> <tng-my-component label="Hello World"></tng-my-component> </section> <section> <h2 class="text-lg font-semibold mb-3">With Props</h2> <tng-my-component label="Disabled" [disabled]="true"></tng-my-component> </section> </div> </div>
-
Add the route in
apps/playground/src/app/app.routes.ts:{ path: '[category]/my-component', loadComponent: () => import('./demos/[category]/my-component/my-component-demo.component').then( (m) => m.MyComponentDemoComponent ), },
Replace
[category]with the appropriate category path (e.g.,form-controls,buttons-indicators, etc.).
-
Add to sidebar navigation in
apps/playground/src/app/app.component.html:<a routerLink="/[category]/my-component" class="flex items-center gap-2 px-3 py-2 rounded-md text-sm text-gray-700 hover:bg-gray-50 transition" routerLinkActive="bg-primary/10 text-primary font-medium" [routerLinkActiveOptions]="{ exact: false }" > <span class="h-2 w-2 rounded-full bg-gray-300"></span> My Component </a>
-
Add to home page in
apps/playground/src/app/home/home.component.ts:{ name: 'My Component', route: '/[category]/my-component', },
- Modify the component in
libs/ui/[component-name]/src/ - Update the demo in
apps/playground/src/app/demos/[category]/[component-name]/ - Test in playground - The changes will be hot-reloaded automatically
-
Start the playground:
yarn playground
-
Navigate to the component:
- Visit the home page to see all components in a tiled layout
- Click on any component tile to view its demo
- Or use the sidebar navigation to browse by category
-
Test different scenarios:
- Update the demo component to test various props and states
- Check responsive behavior
- Test edge cases and error states
Components are organized into the following categories:
- Autocomplete, Checkbox, Chips, Datepicker, Form Field, Input, Radio Button, Select, Slider, Slide Toggle, Timepicker
- Button, Button Toggle, Badge, Icon, Ripples, Progress Bar, Progress Spinner
- Card, Divider, Expansion Panel, Grid List, List, Tabs, Toolbar
- Menu, Sidenav, Stepper, Paginator
- Dialog, Bottom Sheet, Snackbar, Tooltip
- Table, Sort Header, Tree
- Use Angular Signals: Prefer
input()for component inputs instead of@Input() - Standalone Components: All components should be standalone
- Tailwind CSS: Use Tailwind utility classes for styling
- Type Safety: Define types in separate
.types.tsfiles when needed - Variants: Use a
.variants.tsfile for variant classes (seebutton.variants.tsas an example) - Demo Components: Create comprehensive demos showing different use cases
- Naming Convention:
- Component selector:
tng-[component-name] - Component class:
Tailng[ComponentName]Component - Demo component:
[ComponentName]DemoComponent
- Component selector:
Build all projects:
yarn build- Create or update a component in
libs/ui/ - Create/update the demo in
apps/playground/src/app/demos/ - Add/update routes in
app.routes.ts - Update navigation in
app.component.htmlandhome.component.ts - Test in playground by running
yarn playground - Iterate until the component works as expected
tailng/
├── apps/
│ ├── docs/ # Documentation site
│ └── playground/ # Component testing playground
│ └── src/
│ └── app/
│ ├── demos/ # Demo components organized by category
│ ├── home/ # Home page component
│ ├── app.component.* # Main app component with navigation
│ └── app.routes.ts # Route configuration
├── libs/
│ ├── ui/ # UI component library
│ ├── icons/ # Icon components
│ ├── theme/ # Tailwind configuration
│ └── cdk/ # Utilities
└── package.json
cd dist/libs/cdk && npm publish --access public --dry-run
# make sure you're logged in
npm whoami || npm login
# publish in order
cd dist/libs/cdk && npm publish --access public
cd ../theme && npm publish --access public
cd ../icons && npm publish --access public
cd ../ui && npm publish --access public